C1099 [Contest #8] 菜菜种菜 (树状数组+二维偏序)(好题)
发布日期:2021-05-08 15:18:55 浏览次数:25 分类:精选文章

本文共 1237 字,大约阅读时间需要 4 分钟。

在这里插入图片描述
在这里插入图片描述
思路:首先转换以下问题,我们可以设置两个数组L【i】和R【i】,L【i】表示比i的左边所能到达的最近的数,R【i】表示比i的右边所能到达的最近的数,于是问题就转化为了,对于一个查询【l,r】如果i存在贡献的话,i一定满足l<=i<=r并且L【i】<l&&R【i】>r,这个就是典型的偏序问题了。我们还是先固定一遍,我们把查询按右端点固定,然后存一个优先队列表示当前查询下合法的i的集合。
对于当前的查询【li,ri】来说,我们先把i小于等于ri点的先全部存队列,我们假设这些点全部都能产生贡献,然后再查看队列里那些元素不符合条件,把不符合的全部pop同时把他们之前update给还原。

#include 
#define ll long longusing namespace std;const int maxn=1e6+100;#define pi pair
ll c[maxn],a[maxn],l[maxn],r[maxn],ans=0;struct cxk{ int l,r,id;}s[maxn];int lowbit(int x) { return x&-x;}bool cmp(const cxk &a,const cxk &b){ return a.r
0) res+=c[x],x-=lowbit(x); return res;}int main(){ int n,m,q,u,v; scanf("%d %d %d",&n,&m,&q); for(int i=1;i<=n;++i) scanf("%lld",&a[i]),l[i]=0,r[i]=1e9; for(int i=1;i<=m;++i) { scanf("%d %d",&u,&v); if(v
, greater
>qq; for(int i=1;i<=q;++i) { while(now+1<=s[i].r)//先假设全部合法 { qq.push({ r[now+1],now+1}); update(now+1,a[now+1]); update(l[now+1],-a[now+1]); now++; } while(!qq.empty()&&qq.top().first<=now)//把队列里不合法的剔除掉,然后把他们之前的更新给还原 { pi x=qq.top(); qq.pop(); update(x.second,-a[x.second]); update(l[x.second],a[x.second]); } ans^=s[i].id*(query(s[i].r)-query(s[i].l-1)); } printf("%lld\n",ans);}
上一篇:Mail.Ru Cup 2018 Round 2 C. Lucky Days(扩展欧几里得)
下一篇:Codeforces Round #142 (Div. 2) D. Planets(spfa+思维)

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2025年04月20日 07时41分26秒