您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  分块