【BZOJ3932】【CQOI2015】任务查询系统 可持久化线段树
2015-04-08 10:44
375 查看
链接:
#include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/44937681"); }
题解:
首先肯定要用线段树。如果没有强制在线,那么直接把询问排个序然后按秩插入、删除、查询。普通线段树就好了,但是这道题强制在线,就需要可持久化线段树了。
线段树的每个区间记录[x:这段区间有的权值总和]、[n:这段区间有多少个权值][x:这段区间有的权值总和]、[n:这段区间有多少个权值]
然后每个版本表示一个时间点的线段树。
这道题每个版本可能有多个节点被修改,所以我们可以先当成多个版本一个个修改,然后最后一个的版本root记录为当前版本root。这样的时空复杂度基本是严格的。
我们还可以修改时传一个修改区间,见我的代码,可以省一部分空间(可卡,但是无论如何理论时间空间一定更优,时间上存在少许常数)。
代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 101000 #define LOGN 35 #define ls s[now].l #define rs s[now].r #define inf 0x3f3f3f3f using namespace std; struct LSH { int x,id; bool operator < (const LSH &A)const{return x<A.x;} }lsh ; struct OPT { int p,x,d; bool operator < (const OPT &A)const{return p==A.p?x<A.x:p<A.p;} }seq[N<<1]; struct Segment_Tree { int l,r,n; long long x; }s[N*LOGN]; int cnt,root ; inline void pushup(int now) { s[now].x=s[ls].x+s[rs].x; s[now].n=s[ls].n+s[rs].n; } void add(int last,int &now,int l,int r,int sl,int sr) { now=++cnt; if(l==r) { int t=(sr-sl+1); if(seq[sl].d) { s[now].x=s[last].x+(long long)lsh[l].x*t; s[now].n=s[last].n+t; } else { s[now].x=s[last].x-(long long)lsh[l].x*t; s[now].n=s[last].n-t; } return ; } int mid=l+r>>1; if(seq[sr].x<=mid) { rs=s[last].r; add(s[last].l,ls,l,mid,sl,sr); } else if(seq[sl].x>mid) { ls=s[last].l; add(s[last].r,rs,mid+1,r,sl,sr); } else { int p; for(p=sl;seq[p].x<=mid;p++); add(s[last].l,ls,l,mid,sl,p-1); add(s[last].r,rs,mid+1,r,p,sr); } pushup(now); } long long query(int now,int l,int r,int k) { if(k>=s[now].n)return s[now].x; if(l==r)return (long long)k*lsh[l].x; int mid=l+r>>1; if(s[ls].n>=k)return query(ls,l,mid,k); else return s[ls].x+query(rs,mid+1,r,k-s[ls].n); } int n,m,u; long long pre=1; int getk(int a,int b,int c){return 1+(pre*a+b)%c;} int main() { int i,j,k; int a,b,c; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) { scanf("%d%d%d",&a,&b,&c); lsh[i].x=c,lsh[i].id=i; seq[i].p=a,seq[i].d=1,seq[i+n].p=b+1; } sort(lsh+1,lsh+n+1); for(i=1;i<=n;i++) { if(lsh[i].x!=lsh[i-1].x)lsh[++u].x=lsh[i].x; seq[lsh[i].id].x=seq[lsh[i].id+n].x=u; } n<<=1; sort(seq+1,seq+n+1); for(k=0,i=1;i<=n;i=j) { for(k++;k<seq[i].p&&k<=m;k++)root[k]=root[k-1]; if(k>m)break; for(j=i+1;seq[j].p==seq[i].p;j++); add(root[k-1],root[k],1,u,i,j-1); } while(m--) { scanf("%d%d%d%d",&k,&a,&b,&c); pre=query(root[k],1,u,getk(a,b,c)); printf("%lld\n",pre); } return 0; }
相关文章推荐
- BZOJ 3932 CQOI2015 任务查询系统 可持久化线段树
- BZOJ 3932 [CQOI2015]任务查询系统 ——可持久化线段树
- BZOJ 3932 [CQOI2015] 任务查询系统 可持久化线段树
- BZOJ 3932 CQOI 2015 任务查询系统 可持久化线段树
- BZOJ 3932 [CQOI2015]任务查询系统 可持久化线段树
- BZOJ3932 CQOI2015 任务查询系统-可持久化线段树-可持久化平衡树
- [BZOJ3932] [CQOI2015]任务查询系统 && 可持久化线段树
- bzoj 3932 [CQOI2015]任务查询系统 可持久化二维线段树
- bzoj 3932: [CQOI2015]任务查询系统
- [BZOJ3932][CQOI2015]任务查询系统(主席树||树状数组套主席树)
- bzoj 3932 [CQOI2015]任务查询系统(主席树)
- [BZOJ3932]CQOI2015任务查询系统|主席树
- 【BZOJ 3932】[CQOI2015]任务查询系统 主席树
- BZOJ3932: [CQOI2015]任务查询系统 可持久化线段树
- [bzoj3932][CQOI2015][任务查询系统] (主席树)
- 【主席树】bzoj3932 [CQOI2015]任务查询系统
- Bzoj3932--Cqoi2015任务查询系统
- 可持久化线段树 模板 【bzoj3932】任务查询系统
- bzoj3932: [CQOI2015]任务查询系统 主席树
- 【主席树】BZOJ3932-[CQOI2015]任务查询系统