【JZOJ5295】【清华集训模拟】Create(主席树)
2017-08-23 21:57
330 查看
Description
Solution
这题的40分非常的好打,直接倒着主席树一下就好了。其实100分也差不多,只是要发现一些东西。
因为估价函数们是不会变化的,所以我们可以考虑用一个数据结构。
我们对于每个数a,只有大于估价函数的x才是有贡献的,我们可以考虑排序一下x,然后对于每个a找到最大的x小于等于a,然后统计这些区间有多少个覆盖a这个位置,这个可以用主席树来搞。
但是我们对于一段相同的颜色,我们都是可以被相同集合的估价函数来贡献的,所以我们可以考虑把相同颜色端的缩成一个颜色,然后区间询问。(主席树插进来的时候是区间修改)
我们每次修改一段颜色,我们可以暴力合并,这里用线段树或set统计一下就好了。最坏的情况就是一开始两两颜色不相同,然后每隔一个合并一次……最坏合并log次,每次分裂最多两次,最坏2*m次。
Code
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #include<set> #define fo(i,a,b) for(i=a;i<=b;i++) using namespace std; const int maxn=4e5+7; typedef long long ll; int i,j,k,n,m,q,mid,num,kk; ll ans,l,r,x; struct node{ int l,r,bz; ll sum; }t[maxn*40]; struct nod{ int l,r,x; }b[maxn]; bool cmp(nod x,nod y){return x.x<y.x;} int a[maxn],root[maxn]; int c[maxn][3],tot,tt[maxn*4]; void insert(int &x,int y,int l,int r,int z,int o){ if(!x||x==y)x=++num,t[x]=t[y]; if(l==z&&r==o){t[x].sum+=r-l+1;t[x].bz++;return;} int mid=(l+r)/2; if(o<=mid)insert(t[x].l,t[y].l,l,mid,z,o); else if(z>mid)insert(t[x].r,t[y].r,mid+1,r,z,o); else insert(t[x].l,t[y].l,l,mid,z,mid),insert(t[x].r,t[y].r,mid+1,r,mid+1,o); t[x].sum=t[x].bz*(r-l+1)+t[t[x].l].sum+t[t[x].r].sum; } ll find(int x,int l,int r,int z,int o){ if(!x)return 0; if(l==z&&r==o)return t[x].sum; int mid=(l+r)/2; if(o<=mid)return find(t[x].l,l,mid,z,o)+(ll)(o-z+1)*t[x].bz; else if(z>mid)return find(t[x].r,mid+1,r,z,o)+(ll)(o-z+1)*t[x].bz; else return find(t[x].l,l,mid,z,mid)+find(t[x].r,mid+1,r,mid+1,o)+(ll)(o-z+1)*t[x].bz; } int zhao(int x){ int l=1,r=m,mid; while(l<r){ mid=(l+r+1)/2; if(b[mid].x<=x)l=mid;else r=mid-1; } if(b[l].x>x)l--; return l; } void down(int x){ if(tt[x]){ tt[x*2]=tt[x],tt[x*2+1]=tt[x]; tt[x]=0; } } void change(int x,int l,int r,int y,int z,int o){ if(l==y&&r==z){tt[x]=o;return;} down(x); int mid=(l+r)/2; if(z<=mid)change(x*2,l,mid,y,z,o); else if(y>mid)change(x*2+1,mid+1,r,y,z,o); else change(x*2,l,mid,y,mid,o),change(x*2+1,mid+1,r,mid+1,z,o); } int find1(int x,int l,int r,int y){ if(l==r)return tt[x]; int mid=(l+r)/2; down(x); if(y<=mid)return find1(x*2,l,mid,y); else return find1(x*2+1,mid+1,r,y); } int main(){ freopen("create.in","r",stdin); freopen("create.out","w",stdout); scanf("%d%d%d",&n,&m,&q); fo(i,1,n)scanf("%d",&a[i]);a[n+1]=a +1; fo(i,1,n+1){ if(a[i]!=a[i-1]){ if(i>1){ c[++tot][0]=j,c[tot][1]=i-1,c[tot][2]=a[i-1]; change(1,1,n,j,i-1,tot); } j=i; if(i==n+1)continue; } } fo(i,1,m)scanf("%d%d%d",&b[i].l,&b[i].r,&b[i].x); sort(b+1,b+1+m,cmp); fo(i,1,m) insert(root[i],root[i-1],1,n,b[i].l,b[i].r); fo(i,1,tot){ j=zhao(c[i][2]); ans+=find(root[j],1,n,c[i][0],c[i][1]); } printf("%lld\n",ans); while(q--){ scanf("%lld%lld%lld",&l,&r,&x);l^=ans,r^=ans,x^=ans; k=find1(1,1,n,l);while(l<=n&&c[k][2]==x)l=c[k][1]+1,k=find1(1,1,n,l); k=find1(1,1,n,r);while(r&&c[k][2]==x)r=c[k][0]-1,k=find1(1,1,n,r); if(l>r){printf("%lld\n",ans);continue;}c[++tot][0]=l,c[tot][1]=r,c[tot][2]=x;kk=tot; j=zhao(x); ans+=find(root[j],1,n,l,r);k=find1(1,1,n,l); if(l!=c[k][0]){ k=find1(1,1,n,l-1); c[++tot][0]=c[k][0],c[tot][1]=l-1,c[tot][2]=c[k][2]; change(1,1,n,c[tot][0],c[tot][1],tot); } k=find1(1,1,n,l); while(l<=r&&c[k][1]<=r){ j=zhao(c[k][2]);ans-=find(root[j],1,n,l,c[k][1]); change(1,1,n,l,c[k][1],kk); j=c[k][1];c[k][1]=l-1; l=j+1; k=find1(1,1,n,l); } if(l<=r){ j=zhao(c[k][2]);ans-=find(root[j],1,n,l,r);change(1,1,n,l,r,kk); c[k][0]=r+1; } printf("%lld\n",ans); } }
相关文章推荐
- 【JZOJ 5295】【清华集训2017模拟】Create
- 【JZOJ5295】【清华集训2017模拟】Create
- [jzoj]5483. 【清华集训2017模拟11.26】简单路径
- [JZOJ5500]【清华集训2017模拟12.10】营养餐
- JZOJ5483. 【清华集训2017模拟11.26】简单路径
- JZOJ5489. 【清华集训2017模拟11.28】海明距离
- jzoj5498 【清华集训2017模拟12.10】大佬的难题 巧妙容斥
- jzoj5317 【清华集训2017模拟8.19】func (寻找性质)
- 【JZOJ5316】【清华集训模拟】merge(DP、括号序)
- JZOJ5484. 【清华集训2017模拟11.26】快乐树
- JZOJ 5500. 【清华集训2017模拟12.10】营养餐
- JZOJ5498. 【清华集训2017模拟12.10】大佬的难题
- 【JZOJ 5296】【清华集训2017模拟】Sequence
- JZOJ 5483. 【清华集训2017模拟11.26】简单路径
- JZOJ 5485. 【清华集训2017模拟11.26】字符串
- 【JZOJ 5500】【清华集训2017模拟12.10】营养餐
- [JZOJ5495]【清华集训2017模拟12.09】MiniumCut
- 【清华集训2017模拟】Create
- 【JZOJ 5495】【清华集训2017模拟12.09】MiniumCut(最小割树)
- [JZOJ5485]【清华集训2017模拟11.26】字符串