题意:有N个位置,M个操作。操作有两种,每次操作
如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c
如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。
N,M<=50000,N,M<=50000
a<=b<=N
1操作中abs(c)<=N
2操作中c<=Maxlongint
思路:这道题如果外层是位置的话就需要在外层区间更新 并不会写
所以需要外层权值,内层位置
然而常数太渣,BZOJ上过不去
并不想(会)写标记永久化
1 var t:array[0..20000000]of record 2 l,r:longint; 3 a,s:int64; 4 end; 5 op,x,y,z,d:array[1..200000]of longint; 6 root:array[0..1000000]of longint; 7 n,m,up,i,tmp,n1,cnt:longint; 8 9 procedure swap(var x,y:longint); 10 var t:longint; 11 begin 12 t:=x; x:=y; y:=t; 13 end; 14 15 16 function query(l,r,x,y,p:longint):int64; 17 var mid,k:longint; 18 tmp:int64; 19 begin 20 if p=0 then exit(0); 21 mid:=(l+r)>>1; 22 if (t[p].a>0)and(l<r) then 23 begin 24 tmp:=t[p].a; 25 if t[p].l=0 then begin inc(cnt); t[p].l:=cnt; end; 26 k:=t[p].l; 27 t[k].a:=t[k].a+tmp; 28 t[k].s:=t[k].s+tmp*(mid-l+1); 29 if t[p].r=0 then begin inc(cnt); t[p].r:=cnt; end; 30 k:=t[p].r; 31 t[k].a:=t[k].a+tmp; 32 t[k].s:=t[k].s+tmp*(r-mid); 33 t[p].a:=0; 34 end; 35 if (l>=x)and(r<=y) then exit(t[p].s); 36 query:=0; 37 if x<=mid then query:=query+query(l,mid,x,y,t[p].l); 38 if y>mid then query:=query+query(mid+1,r,x,y,t[p].r); 39 40 end; 41 42 procedure update(l,r,x,y:longint;var p:longint); 43 var mid,k:longint; 44 tmp:int64; 45 begin 46 if p=0 then begin inc(cnt); p:=cnt; end; 47 mid:=(l+r)>>1; 48 if (t[p].a>0)and(l<r) then 49 begin 50 tmp:=t[p].a; 51 if t[p].l=0 then begin inc(cnt); t[p].l:=cnt; end; 52 k:=t[p].l; 53 t[k].a:=t[k].a+tmp; 54 t[k].s:=t[k].s+tmp*(mid-l+1); 55 if t[p].r=0 then begin inc(cnt); t[p].r:=cnt; end; 56 k:=t[p].r; 57 t[k].a:=t[k].a+tmp; 58 t[k].s:=t[k].s+tmp*(r-mid); 59 t[p].a:=0; 60 end; 61 if (l>=x)and(r<=y) then 62 begin 63 t[p].a:=t[p].a+1; 64 t[p].s:=t[p].s+r-l+1; 65 exit; 66 end; 67 if x<=mid then update(l,mid,x,y,t[p].l); 68 if y>mid then update(mid+1,r,x,y,t[p].r); 69 70 t[p].s:=t[t[p].l].s+t[t[p].r].s; 71 end; 72 73 procedure add(a,b,c:longint); 74 var l,r,k,mid:longint; 75 begin 76 l:=1; r:=n+n+1; k:=1; 77 while l<r do 78 begin 79 mid:=(l+r)>>1; 80 update(1,n,a,b,root[k]); 81 if c<=mid then 82 begin 83 r:=mid; k:=k<<1; 84 end 85 else 86 begin 87 l:=mid+1; k:=(k<<1)+1; 88 end; 89 end; 90 update(1,n,a,b,root[k]); 91 end; 92 93 function ask(a,b:longint;c:int64):longint; 94 var l,r,mid,k:longint; 95 tmp:int64; 96 begin 97 l:=1; r:=n+n+1; k:=1; 98 while l<r do 99 begin 100 mid:=(l+r)>>1; 101 tmp:=query(1,n,a,b,root[k<<1]); 102 if tmp>=c then 103 begin 104 r:=mid; k:=k<<1; 105 end 106 else 107 begin 108 l:=mid+1; k:=(k<<1)+1; 109 c:=c-tmp; 110 end; 111 end; 112 exit(l); 113 end; 114 115 begin 116 117 readln(n,m); 118 for i:=1 to m do read(op[i],x[i],y[i],z[i]); 119 120 for i:=1 to m do 121 if op[i]=1 then add(x[i],y[i],n+1-z[i]) 122 123 else writeln(n+1-ask(x[i],y[i],z[i])); 124 125 126 127 end.
2017.3.19
想了想还是学一波奇技淫巧
需要注意的是标记永久化只能用(l=x)and(r=y)的写法写
1 var t:array[0..20000000]of record 2 l,r:longint; 3 a,s:int64; 4 end; 5 op,x,y,z,d:array[1..200000]of longint; 6 root:array[0..1000000]of longint; 7 n,m,up,i,tmp,n1,cnt:longint; 8 9 procedure swap(var x,y:longint); 10 var t:longint; 11 begin 12 t:=x; x:=y; y:=t; 13 end; 14 15 procedure pushup(l,r,p:longint); 16 begin 17 t[p].s:=t[t[p].l].s+t[t[p].r].s+t[p].a*(r-l+1); 18 end; 19 20 function query(l,r,x,y,p:longint):int64; 21 var mid:longint; 22 ans:int64; 23 begin 24 if p=0 then exit(0); 25 if (l=x)and(r=y) then exit(t[p].s); 26 mid:=(l+r)>>1; 27 query:=0; 28 ans:=t[p].a*(y-x+1); 29 if y<=mid then exit(query(l,mid,x,y,t[p].l)+ans) 30 else if x>mid then exit(query(mid+1,r,x,y,t[p].r)+ans) 31 else exit(query(l,mid,x,mid,t[p].l)+query(mid+1,r,mid+1,y,t[p].r)+ans); 32 end; 33 34 procedure update(l,r,x,y:longint;var p:longint); 35 var mid,k:longint; 36 tmp:int64; 37 begin 38 if p=0 then begin inc(cnt); p:=cnt; end; 39 mid:=(l+r)>>1; 40 if (l=x)and(r=y) then 41 begin 42 t[p].a:=t[p].a+1; 43 t[p].s:=t[p].s+r-l+1; 44 exit; 45 end; 46 if y<=mid then update(l,mid,x,y,t[p].l) 47 else if x>mid then update(mid+1,r,x,y,t[p].r) 48 else 49 begin 50 update(l,mid,x,mid,t[p].l); 51 update(mid+1,r,mid+1,y,t[p].r); 52 end; 53 pushup(l,r,p); 54 end; 55 56 procedure add(a,b,c:longint); 57 var l,r,k,mid:longint; 58 begin 59 l:=1; r:=n+n+1; k:=1; 60 while l<r do 61 begin 62 mid:=(l+r)>>1; 63 update(1,n,a,b,root[k]); 64 if c<=mid then 65 begin 66 r:=mid; k:=k<<1; 67 end 68 else 69 begin 70 l:=mid+1; k:=(k<<1)+1; 71 end; 72 end; 73 update(1,n,a,b,root[k]); 74 end; 75 76 function ask(a,b:longint;c:int64):longint; 77 var l,r,mid,k:longint; 78 tmp:int64; 79 begin 80 l:=1; r:=n+n+1; k:=1; 81 while l<r do 82 begin 83 mid:=(l+r)>>1; 84 tmp:=query(1,n,a,b,root[k<<1]); 85 if tmp>=c then 86 begin 87 r:=mid; k:=k<<1; 88 end 89 else 90 begin 91 l:=mid+1; k:=(k<<1)+1; 92 c:=c-tmp; 93 end; 94 end; 95 exit(l); 96 end; 97 98 begin 99 100 readln(n,m); 101 for i:=1 to m do read(op[i],x[i],y[i],z[i]); 102 103 for i:=1 to m do 104 if op[i]=1 then add(x[i],y[i],n+1-z[i]) 105 106 else writeln(n+1-ask(x[i],y[i],z[i])); 107 108 109 110 end.
整体二分是二分答案,CDQ分治是二分操作序列
比树套树快2倍
1 var a,b:array[1..100000]of record 2 l,r,id,op:longint; 3 w:int64; 4 end; 5 s1,s2:array[1..100000]of int64; 6 flag,ans:array[1..100000]of longint; 7 n,m,i,cnt:longint; 8 9 function lowbit(x:longint):longint; 10 begin 11 exit(x and (-x)); 12 end; 13 14 procedure add(x,y:longint); 15 var i:longint; 16 begin 17 i:=x; 18 while i<=n do 19 begin 20 s1[i]:=s1[i]+y; 21 s2[i]:=s2[i]+y*x; 22 i:=i+lowbit(i); 23 end; 24 end; 25 26 procedure update(a,b,c:longint); 27 begin 28 add(a,c); add(b+1,-c); 29 end; 30 31 function query(x:longint):int64; 32 var i:longint; 33 begin 34 i:=x; query:=0; 35 while i>0 do 36 begin 37 query:=query+s1[i]*(x+1)-s2[i]; 38 i:=i-lowbit(i); 39 end; 40 end; 41 42 function ask(a,b:longint):int64; 43 begin 44 exit(query(b)-query(a-1)); 45 end; 46 47 procedure solve(x,y,l,r:longint); 48 var i,mid,pre,now:longint; 49 tmp:int64; 50 begin 51 if l=r then 52 begin 53 for i:=x to y do 54 if a[i].op=2 then ans[a[i].id]:=l; 55 exit; 56 end; 57 mid:=(l+r)>>1; 58 pre:=x; now:=x; 59 for i:=x to y do 60 if a[i].op=1 then 61 begin 62 if a[i].w<=mid then 63 begin 64 update(a[i].l,a[i].r,1); 65 flag[i]:=0; 66 inc(now); 67 end 68 else flag[i]:=1; 69 end 70 else 71 begin 72 tmp:=ask(a[i].l,a[i].r); 73 if tmp>=a[i].w then 74 begin 75 inc(now); flag[i]:=0; 76 end 77 else 78 begin 79 flag[i]:=1; 80 a[i].w:=a[i].w-tmp; 81 end; 82 end; 83 for i:=x to y do 84 if (a[i].op=1)and(a[i].w<=mid) then update(a[i].l,a[i].r,-1); 85 for i:=x to y do 86 if flag[i]=1 then 87 begin 88 b[now]:=a[i]; inc(now); 89 end 90 else 91 begin 92 b[pre]:=a[i]; inc(pre); 93 end; 94 for i:=x to y do a[i]:=b[i]; 95 solve(x,pre-1,l,mid); 96 solve(pre,y,mid+1,r); 97 end; 98 99 begin 100 assign(input,'bzoj3110.in'); reset(input); 101 assign(output,'bzoj3110.out'); rewrite(output); 102 read(n,m); 103 for i:=1 to m do 104 begin 105 read(a[i].op,a[i].l,a[i].r,a[i].w); 106 if a[i].op=1 then a[i].w:=n-a[i].w+1 107 else 108 begin 109 inc(cnt); a[i].id:=cnt; 110 end; 111 end; 112 solve(1,m,1,2*n+1); 113 for i:=1 to cnt do writeln(n-ans[i]+1); 114 close(input); 115 close(output); 116 end.