BZOJ 3343: 教主的魔法|分块
2016-01-23 08:03
295 查看
分块暴力对每一个块排序,询问如果跨过了整个块,那么就查询整个块,对排好序的块二分答案,两边在块外的就暴力排序,二分答案
区间修改如果跨过了整个块,就在块上标记,否则暴力修改,重新给块排序
区间修改如果跨过了整个块,就在块上标记,否则暴力修改,重新给块排序
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<queue> #include<vector> #include<set> #include<map> #include<iostream> #include<algorithm> using namespace std; int sc() { int i=0;char c=getchar(); while(c>'9'||c<'0')c=getchar(); while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar(); return i; } int a[1000005],block_st[1005][1005],block_tag[1005],block_sum[1005]; int bl[1000005],st[2222]; int block,m,n; bool cmp(int a,int b){return a>b;} int find(int *w,int r,int K) { int l=1,ans=0; while(l<=r) { int mid=l+r>>1; if(w[mid]>=K)ans=mid,l=mid+1; else r=mid-1; } return ans; } int main() { n=sc(),m=sc();block=sqrt(n); for(int i=1;i<=n;i++)a[i]=sc(); for(int i=1;i<=n;i++) { bl[i]=(i-1)/block+1; block_sum[(i-1)/block+1]++; block_st[(i-1)/block+1][block_sum[(i-1)/block+1]]=a[i]; } for(int i=1;i*block+1<=n;i++) sort(block_st[i]+1,block_st[i]+block_sum[i]+1,cmp); for(int i=1;i<=m;i++) { char s[5]; scanf("%s",s); if(s[0]=='A') { int l=sc(),r=sc(),k=sc(); if(bl[l]==bl[r]) { int top=0; for(int j=l;j<=r;j++)st[++top]=a[j]; sort(st+1,st+top+1,cmp); printf("%d\n",find(st,top,k)); } else { int x=bl[l],y=bl[r]; int ans=0,top=0; for(int j=x+1;j<y;j++) ans+=find(block_st[j],block_sum[j],k-block_tag[j]); for(int j=l;bl[j]==bl[l];j++) st[++top]=a[j]+block_tag[x]; for(int j=r;bl[j]==bl[r];j--) st[++top]=a[j]+block_tag[y]; sort(st+1,st+top+1,cmp); printf("%d\n",ans+find(st,top,k)); } } else { int l=sc(),r=sc(),k=sc(); if(bl[l]==bl[r]) { for(int j=l;j<=r;j++)a[j]+=k; int top=0,x=bl[l]; for(int j=(x-1)*block+1;bl[j]==x;j++)block_st[x][++top]=a[j]; sort(block_st[x]+1,block_st[x]+top+1,cmp); } else { int x=bl[l],y=bl[r],top; for(int j=x+1;j<y;j++)block_tag[j]+=k; for(int j=l;bl[j]==x;j++)a[j]+=k; for(int j=r;bl[j]==y;j--)a[j]+=k; top=0; for(int j=(x-1)*block+1;bl[j]==x;j++)block_st[x][++top]=a[j]; sort(block_st[x]+1,block_st[x]+top+1,cmp); top=0; for(int j=(y-1)*block+1;bl[j]==y;j++)block_st[y][++top]=a[j]; sort(block_st[y]+1,block_st[y]+top+1,cmp); } } } return 0; }
相关文章推荐
- [BZOJ2038][2009国家集训队][莫队][分块]小z的袜子
- Codeforces538F A Heap of Heaps【分块+差分求前缀和】
- 大矩阵的分块乘法及matlab实现
- bzoj-2741 L
- bzoj-3585 mex
- bzoj-2051 A Problem For Fun
- 算法马拉松8(差和问题)
- 1290 Counting Diff Pairs
- 【Violet 6】【BZOJ2724】蒲公英
- 【BZOJ4320】Homework
- 【BZOJ4216】Pig
- [2009国家集训队]小Z的袜子(hose) 分块做法
- NBUT 1457 分块
- codeforces #307 E. GukiZ and GukiZiana (分块)
- Codeforces Round #307 (Div. 2)E. GukiZ and GukiZiana(分块)
- 【分块】 CF 551 E GukiZ and GukiZiana
- Codeforces Round #307 (Div. 2) E. GukiZ and GukiZiana (分块)
- Codeforces Gym 100589A Queries on the Tree(树状数组+分块)
- HDU 4467 Graph(分块)
- GFS中的数据完整性校验