bzoj2453
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2453
题目大意:
(1) 若第一个字母为“M”,则紧接着有三个数字L、R、W。表示对闭区间 [L, R] 内所有英雄的身高加上W。
(2) 若第一个字母为“A”,则紧接着有三个数字L、R、C。询问闭区间 [L, R] 内有多少英雄的身高大于等于C。
题解:分块+二分咯
代码:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<cmath> 6 #define maxn 1000001 7 using namespace std; 8 int add[maxn],a[maxn],b[maxn],pos[maxn]; 9 char ch[5]; 10 int n,m,blo,num; 11 int read() 12 { 13 int x=0; char ch; bool bo=0; 14 while (ch=getchar(),ch<'0'||ch>'9') if (ch=='-') bo=1; 15 while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9'); 16 if (bo) return -x; return x; 17 } 18 void resort(int x) 19 { 20 int l=(x-1)*blo+1,r=min(x*blo,n); 21 for (int i=l; i<=r; i++) 22 b[i]=a[i]; 23 sort(b+l,b+r+1); 24 } 25 int find(int x,int v) 26 { 27 int l=(x-1)*blo+1,r=min(x*blo,n); 28 int last=r; 29 while (l<=r) 30 { 31 int mid=(l+r)>>1; 32 if (b[mid]<v) l=mid+1; 33 else r=mid-1; 34 } 35 return last-l+1; 36 } 37 int query(int x,int y,int v) 38 { 39 int sum=0; 40 if (pos[x]==pos[y]) 41 { 42 for (int i=x; i<=y; i++) 43 if (a[i]+add[pos[i]]>=v) sum++; 44 } 45 else 46 { 47 for(int i=x;i<=pos[x]*blo;i++) 48 if(a[i]+add[pos[i]]>=v)sum++; 49 for(int i=(pos[y]-1)*blo+1;i<=y;i++) 50 if(a[i]+add[pos[i]]>=v)sum++; 51 } 52 for (int i=pos[x]+1; i<pos[y]; i++) 53 sum+=find(i,v-add[i]); 54 return sum; 55 } 56 void ins(int x,int y,int v) 57 { 58 if (pos[x]==pos[y]) 59 { 60 for (int i=x; i<=y; i++) a[i]+=v; 61 } 62 else 63 { 64 for (int i=x; i<=blo*pos[x]; i++) a[i]+=v; 65 for (int i=(pos[y]-1)*blo+1; i<=y; i++) a[i]+=v; 66 } 67 resort(pos[x]); resort(pos[y]); 68 for (int i=pos[x]+1; i<pos[y]; i++) 69 add[i]+=v; 70 } 71 int main() 72 { 73 n=read(); m=read(); 74 blo=int(sqrt(n)); 75 for (int i=1; i<=n; i++) a[i]=b[i]=read(),pos[i]=(i-1)/blo+1; 76 num=(n-1)/blo+1; 77 for (int i=1; i<=num; i++) resort(i); 78 for (int i=1; i<=m; i++) 79 { 80 scanf("%s",ch+1); int x=read(),y=read(),z=read(); 81 if (ch[1]=='M') ins(x,y,z); 82 else printf("%d\n",query(x,y,z)); 83 } 84 }
我太蒟蒻了,所以神犇们留下意见让我跪膜