题目大意:带修改的区间第K小
题解:
整体二分
啊看了某个大神说,这是奇技淫巧orzorzorz
因为多了修改,而修改前已经对树状数组产生了影响,所以在面对一个修改操作的时候要先把之前的影响去掉。
how?(奇技淫巧来了。。。
对于同一个点上的修改,在修改操作之前增加一个操作,标记为tag=3,就表示把之前的值的贡献减掉。[tag=1表示修改,tag=2表示询问
因为操作序列是按时间维度来排的序,而且在分治时的顺序是严格不变的。所以在执行修改操作之前因为加了上面那个操作就已经处理完了,嗯所以一点问题都没有[我纠结了这个纠结了好久qwq。
坑爹的hdu是多组数据qwq好吧是我瞎,还以为跟bzoj上的差不多。对拍了一个早上!!!
简直了!
bzoj1901:
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define maxn 50100 #define inf 0x7fffffff struct node { int x,y,c,tg,ans; }q[maxn];int n,m,num; int id[maxn],cur[maxn],tmp[maxn]; int tol[maxn],tor[maxn],c[maxn],a[maxn]; int lowbit(int x){return x&(-x);} void change(int x,int k) { for (x;x<=n;x+=lowbit(x)) c[x]+=k; } int query(int x) { int ret=0; for (x;x>0;x-=lowbit(x)) ret+=c[x]; return ret; } void solve(int head,int tail,int l,int r) { if (head>tail) return; int i,lnum=0,rnum=0; int mid=(l+r)>>1; if (l==r) { for (i=head;i<=tail;i++) if (q[id[i]].tg==2) q[id[i]].ans=l; return; } for (i=head;i<=tail;i++) if (q[id[i]].tg==1) { if (q[id[i]].x<=mid) tol[++lnum]=id[i],change(q[id[i]].y,1); else tor[++rnum]=id[i]; } else if (q[id[i]].tg==3) { if (q[id[i]].x<=mid) tol[++lnum]=id[i],change(q[id[i]].y,-1); else tor[++rnum]=id[i]; } else { tmp[id[i]]=query(q[id[i]].y)-query(q[id[i]].x-1); if (tmp[id[i]]+cur[id[i]]>=q[id[i]].c) tol[++lnum]=id[i]; else cur[id[i]]+=tmp[id[i]],tor[++rnum]=id[i]; } for (i=head;i<=tail;i++) if (q[id[i]].tg==1 && q[id[i]].x<=mid) change(q[id[i]].y,-1); else if (q[id[i]].tg==3 && q[id[i]].x<=mid) change(q[id[i]].y,1); for (i=0;i<lnum;i++) id[head+i]=tol[i+1]; for (i=0;i<rnum;i++) id[head+i+lnum]=tor[i+1]; solve(head,head+lnum-1,l,mid); solve(head+lnum,tail,mid+1,r); } int main() { char cc;int i;num=0; scanf("%d%d",&n,&m); memset(c,0,sizeof(c)); for (i=1;i<=n;i++) { id[++num]=num; scanf("%d",&q[num].x); q[num].y=i;q[num].tg=1; a[i]=q[num].x; } for (i=1;i<=m;i++) { scanf(" %c",&cc); if (cc=='C') { id[++num]=num;q[num].tg=3;id[++num]=num; scanf("%d%d",&q[num].y,&q[num].x); q[num-1].y=q[num].y;q[num-1].x=a[q[num].y]; q[num].tg=1;a[q[num].y]=q[num].x; }else { id[++num]=num; scanf("%d%d%d",&q[num].x,&q[num].y,&q[num].c); q[num].tg=2;q[num].ans=0; } } solve(1,num,0,inf); for (i=1;i<=num;i++) if (q[i].tg==2) printf("%d ",q[i].ans); return 0; }
hdu5412:
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define maxn 310000 #define inf 1e9 typedef long long LL; struct node { LL l,r,c,tg;LL ans; }q[maxn];LL n,m,c[maxn],id[maxn]; LL cur[maxn],tol[maxn],tor[maxn],a[maxn]; LL lowbit(LL x){return x&(-x);} void change(LL x,LL k) { for (x;x<=n;x+=lowbit(x)) c[x]+=k; } LL query(LL x) { LL ret=0; for (x;x>0;x-=lowbit(x)) ret+=c[x]; return ret; } void solve(LL head,LL tail,LL l,LL r) { if (head>tail) return; LL lnum=0,rnum=0,i;LL mid=(l+r)>>1; if (l==r) { for (i=head;i<=tail;i++) if (q[id[i]].tg==2) q[id[i]].ans=l; return; } for (i=head;i<=tail;i++) if (q[id[i]].tg==1) { if (q[id[i]].r<=mid) change(q[id[i]].l,1),tol[++lnum]=id[i]; else tor[++rnum]=id[i]; } else if (q[id[i]].tg==3) { if (q[id[i]].r<=mid) change(q[id[i]].l,-1),tol[++lnum]=id[i]; else tor[++rnum]=id[i]; } else { LL now=query(q[id[i]].r)-query(q[id[i]].l-1); if (now+cur[id[i]]>=q[id[i]].c) tol[++lnum]=id[i]; else cur[id[i]]+=now,tor[++rnum]=id[i]; } for (i=head;i<=tail;i++) if (q[id[i]].tg==1 && q[id[i]].r<=mid) change(q[id[i]].l,-1); else if (q[id[i]].tg==3 && q[id[i]].r<=mid) change(q[id[i]].l,1); for (i=0;i<lnum;i++) id[head+i]=tol[i+1]; for (i=0;i<rnum;i++) id[head+i+lnum]=tor[i+1]; solve(head,head+lnum-1,l,mid); solve(head+lnum,tail,mid+1,r); } int main() { //freopen("a.in","r",stdin); //freopen("a.out","w",stdout); LL x,i,cc,l,r,t; while (scanf("%lld",&n)!=EOF) { memset(c,0,sizeof(c));t=0; memset(cur,0,sizeof(cur)); for (i=1;i<=n;i++) { scanf("%lld",&x); id[++t]=t;a[i]=x; q[t].l=i;q[t].r=x;q[t].tg=1; } scanf("%lld",&m); for (i=1;i<=m;i++) { scanf("%lld%lld%lld",&cc,&l,&r); if (cc==1) { id[++t]=t;q[t].l=l;q[t].r=a[l];q[t].tg=3; id[++t]=t;q[t].l=l;q[t].r=r;q[t].tg=1;a[l]=r; }else { scanf("%lld",&x);id[++t]=t; q[t].c=x;q[t].l=l;q[t].r=r;q[t].tg=2; } } solve(1,t,1,inf); for (i=1;i<=t;i++) if (q[i].tg==2) printf("%lld ",q[i].ans); } return 0; }