网上几乎清一色树套树,但是我就写个整体二分吧(其实是我不会树套树……)
这题还是和原来步骤一样,二分-判定-划分,当二分答案为m的时候
询问:大于等于m的个数大于等于k那就可能追求更大,划到右边;
不满足意味着答案要更小,那些大于等于m的修改操作对询问影响不变,k减去他们贡献的个数,划到左边
修改:显然大于等于m的划到右边,小于m划到左边
两个部分内都是操作都是按时间线的顺序的
注意这里的修改是——区间修改,区间查询……不好要上线段树?
突然想起来树状数组也是可以解决区间求改区间查询的
首先我们知道,区间修改时要维护一个差分数组d[i],代表[i..n]都加上d[i]
区间修改就是对d[l]+,d[r+1]-,然后每个位置的修改总和就等于d[]的前缀和 这就是单点查询
区间查询怎么办?我们还是想方设法变成前缀和,我们知道[l,r]=sum(r)-sum(l-1)
而sum[x]这个前缀和又怎么求呢?我们知道sum[x]=sumpre[x](初始和)+sumdelta[x](增量和)
重点是增量和,结合刚才的区间修改d[],我们发现,sumdelta[x]=∑d[i]*(x-i+1)=(x+1)*∑d[i]-∑d[i]*i
然后显然我们维护两个树状数组d[i]和d[i]*i即可
这题就解决了,没有tle,zjoi良心了一把……

UPD:这题啊现在在bzoj上非常坑,因为加强了数据……

转c++练模板的时候发现的,为什么不弄个hack……害得我以为c++有什么特殊之处呢……

坑点是50000*50000爆了树状数组统计时的int,换成unsigned int就好……

上面那个pascal程序我也顺便改了%%%(pascal范围检测比c++严格……)

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 
  7 using namespace std;
  8 struct node{int op,l,r,k,p;} a[50010],b[50010];
  9 int q[50010],g[50010][2],c[50010],d[50010],ans[50010];
 10 bool can[50010],v[50010];
 11 int n,m,t,tot,p;
 12 
 13 int read()
 14 {
 15     int x=0,f=1;char ch=getchar();
 16     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 17     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 18     return x*f;
 19 }
 20 void work(int x,int w,int f)
 21 {
 22      for (int i=x; i<=n; i+=i&-i)
 23      {
 24          if (!v[i]) {v[i]=1; q[++tot]=i;}
 25          g[i][f]+=w;
 26      }
 27 }
 28 
 29 int ask(int x,int f)
 30 {
 31      int s=0;
 32      for (int i=x;i; i-=i&-i) s+=g[i][f];
 33      return s;
 34 }
 35 
 36 unsigned int sum(int x) //注意啊注意啊……
 37 {
 38     return (x+1)*ask(x,0)-ask(x,1);
 39 }
 40 
 41 void cdq(int l,int r,int f,int t)
 42 {
 43      if (l>r||f>t) return;
 44      int m=(l+r)>>1,h; tot=h=0;
 45      for (int i=f; i<=t; i++)
 46        if (a[i].op==1&&a[i].k>=d[m])
 47        {
 48           work(a[i].l,1,0);
 49           work(a[i].r+1,-1,0);
 50           work(a[i].l,a[i].l,1);
 51           work(a[i].r+1,-a[i].r-1,1);
 52           can[i]=1; ++h;
 53        }
 54        else if (a[i].op==2)
 55        {
 56           unsigned int s=sum(a[i].r)-sum(a[i].l-1);  
 57           if (s>=a[i].k)
 58           {
 59              ans[a[i].p]=m;
 60              can[i]=1; ++h;
 61           }
 62           else a[i].k-=s;
 63        }
 64      
 65      for (int i=1; i<=tot; i++)
 66      {
 67          int x=q[i]; v[x]=0;
 68          g[x][0]=g[x][1]=0;
 69      }
 70      int f1=f,f2=t-h+1;
 71      for (int i=f; i<=t; i++)
 72        if (can[i]) 
 73        {
 74           b[f2++]=a[i];
 75           can[i]=0;
 76        }
 77        else b[f1++]=a[i];
 78      for (int i=f; i<=t; i++)
 79        a[i]=b[i];  
 80      cdq(l,m-1,f,f1-1);
 81      cdq(m+1,r,f1,t);
 82 }  
 83      
 84 int main()
 85 {
 86     n=read(); m=read();
 87     for (int i=1;i<=m; i++)
 88     {
 89         a[i].op=read(); a[i].l=read(); a[i].r=read(); a[i].k=read();
 90         a[i].p=i;
 91         if (a[i].op==1) c[++t]=a[i].k;
 92     }
 93     sort(c+1,c+t+1);
 94     p=1; d[1]=c[1];
 95     for (int i=2;i<=t; i++)
 96       if (c[i]!=c[i-1]) d[++p]=c[i];
 97         
 98     cdq(1,p,1,m);  
 99     for (int i=1;i<=m;i++)
100       if (ans[i]) printf("%d\n",d[ans[i]]);
101     return 0;
102 }  
c++版
  1 type node=record
  2        l,r,k,op,p:longint;
  3      end;
  4 
  5 var a,b:array[0..50010] of node;
  6     q,ans,c,g,d:array[0..50010] of longint;
  7     v1,v2:array[0..50010] of boolean;
  8     i,t,n,m,tot,p:longint;
  9 
 10 procedure swap(var a,b:longint);
 11   var c:longint;
 12   begin
 13     c:=a;
 14     a:=b;
 15     b:=c;
 16   end;
 17 
 18 procedure sort(l,r:longint);
 19   var i,j,x:longint;
 20   begin
 21     i:=l;
 22     j:=r;
 23     x:=c[(l+r) shr 1];
 24     repeat
 25       while c[i]<x do inc(i);
 26       while x<c[j] do dec(j);
 27       if not(i>j) then
 28       begin
 29         swap(c[i],c[j]);
 30         inc(i);
 31         dec(j);
 32       end;
 33     until i>j;
 34     if l<j then sort(l,j);
 35     if i<r then sort(i,r);
 36   end;
 37 
 38 function lowbit(x:longint):longint;
 39   begin
 40     exit(x and (-x));
 41   end;
 42 
 43 procedure addc(x,w:longint);
 44   begin
 45     while x<=n do
 46     begin
 47       if not v2[x] then
 48       begin
 49         v2[x]:=true;
 50         inc(tot);
 51         q[tot]:=x;
 52       end;
 53       inc(c[x],w);
 54       x:=x+lowbit(x);
 55     end;
 56   end;
 57 
 58 procedure addg(x,w:longint);
 59   begin
 60     while x<=n do
 61     begin
 62       inc(g[x],w);
 63       x:=x+lowbit(x);
 64     end;
 65   end;
 66 
 67 function askc(x:longint):longint;
 68   begin
 69     askc:=0;
 70     while x>0 do
 71     begin
 72       askc:=askc+c[x];
 73       x:=x-lowbit(x);
 74     end;
 75   end;
 76 
 77 function askg(x:longint):longint;
 78   begin
 79     askg:=0;
 80     while x>0 do
 81     begin
 82       askg:=askg+g[x];
 83       x:=x-lowbit(x);
 84     end;
 85   end;
 86 
 87 function sum(x:longint):longword;
 88   begin
 89     exit(longword(askg(x))*longword(x+1)-askc(x)); //pascal范围检测严格……
 90   end;
 91 
 92 procedure cdq(l,r,f,t:longint);
 93   var m,h,l1,l2:longint;
 94       s:longword;
 95   begin
 96     if (f>t) or (l>r) then exit;
 97     m:=(l+r) shr 1;
 98     h:=0; tot:=0;
 99     for i:=f to t do
100       if (a[i].op=1) and (a[i].k>=d[m]) then
101       begin
102         addg(a[i].l,1);
103         addg(a[i].r+1,-1);
104         addc(a[i].l,a[i].l);
105         addc(a[i].r+1,-a[i].r-1);
106         v1[i]:=true; inc(h);
107       end
108       else if (a[i].op=2) then
109       begin
110         s:=sum(a[i].r)-sum(a[i].l-1);
111         if s>=a[i].k then
112         begin
113           ans[a[i].p]:=m;
114           v1[i]:=true;  inc(h);
115         end
116         else a[i].k:=a[i].k-s;
117       end;
118 
119     for i:=1 to tot do
120     begin
121       c[q[i]]:=0;
122       g[q[i]]:=0;
123       v2[q[i]]:=false;
124     end;
125     l1:=f; l2:=t-h+1;
126     for i:=f to t do
127       if v1[i] then
128       begin
129         b[l2]:=a[i];
130         inc(l2);
131         v1[i]:=false;
132       end
133       else begin
134         b[l1]:=a[i];
135         inc(l1);
136       end;
137 
138     for i:=f to t do
139       a[i]:=b[i];
140 
141     cdq(l,m-1,f,l1-1);
142     cdq(m+1,r,l1,t);
143   end;
144 
145 begin
146   readln(n,m);
147   for i:=1 to m do
148   begin
149     readln(a[i].op,a[i].l,a[i].r,a[i].k);
150     a[i].p:=i;
151     if a[i].op=1 then
152     begin
153       inc(t);
154       c[t]:=a[i].k;
155     end;
156   end;
157   sort(1,t);
158   p:=1;
159   d[1]:=c[1];
160   for i:=2 to t do
161     if c[i]<>c[i-1] then
162     begin
163       inc(p);
164       d[p]:=c[i];
165     end;
166 
167   fillchar(c,sizeof(c),0);
168   cdq(1,p,1,m);
169   for i:=1 to m do
170     if ans[i]<>0 then writeln(d[ans[i]]);
171 end.
pascal版

 

posted on 2015-04-06 22:34  acphile  阅读(187)  评论(0编辑  收藏  举报