您的位置:首页 > 其它

bzoj 2120 数颜色 待修改的莫队

2017-04-29 19:51 246 查看
题目链接点这里

,相比较,,一般莫队,,只需要排序的时候,,先按l所在块排序,,再按r所在块排序,再按查询时间排序就可以了

#include<algorithm>
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cmath>
using namespace std;
#define mem(x,y) memset(x,y,sizeof(x))
#define FIN freopen("input.txt","r",stdin)
#define fuck(x) cout<<x<<endl
const double eps=1e-7;
const int MX=11111;
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
typedef long long LL;
typedef pair<LL,LL> PLL;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int n,m,block;
struct Q
{
int l,r,pre,id;
bool operator <(const Q a)const
{
if(l/block!=a.l/block)return l/block<a.l/block;
else if(r/block!=a.r/block) return r/block<a.r/block;
return pre<a.pre;
}
} q[MX];
int w[MX*111],arr[MX],arr1[MX],ans[MX],xiugai[MX][3];
void add(int x,int&cnt)
{
if(w[arr[x]]==0) cnt++;
w[arr[x]]++;
}
void del(int x,int &cnt)
{
if(w[arr[x]]==1) cnt--;
w[arr[x]]--;
}
void change(int x,int d,int &cnt,int l,int r)
{
if(x<l||x>r)arr[x]=d;
else
{
if(w[arr[x]]==1)cnt--;
w[arr[x]]--;
arr[x]=d;
if(w[arr[x]]==0)cnt++;
w[arr[x]]++;
}
}
int main()
{
FIN;
while(cin>>n>>m)
{
block=(int)pow(n+0.5,2.0/3);
for(int i=0; i<n; i++)
{
scanf("%d",&arr[i]);
arr1[i]=arr[i];
}
int cnt1=0,cnt2=1;
for(int i=0; i<m; i++)
{
char s[11];
int l,r;
scanf("%s%d%d",s,&l,&r);
if(s[0]=='Q')
{
l--,r--;
q[cnt1].l=l;
q[cnt1].r=r;
q[cnt1].id=cnt1;
q[cnt1++].pre=cnt2-1;
}
else
{
l--;
xiugai[cnt2][2]=arr1[l];//记录本次修改前的颜色
arr1[l]=r;
xiugai[cnt2][0]=l;
xiugai[cnt2++][1]=r;
}
}
sort(q,q+cnt1); //cout<<"q"<<endl;
mem(w,0);
int l=0,r=-1,now=0,cnt=0;
for(int i=0; i<cnt1; i++)
{
while(l<q[i].l)del(l++,cnt);
while(l>q[i].l)add(--l,cnt);
while(r<q[i].r)add(++r,cnt);
while(r>q[i].r)del(r--,cnt);
while(now<q[i].pre) change(xiugai[now+1][0],xiugai[now+1][1],cnt,l,r),now++;
while(now>q[i].pre) change(xiugai[now][0],xiugai[now][2],cnt,l,r),now--;
ans[q[i].id]=cnt;
}
for(int i=0; i<cnt1; i++)printf("%d\n",ans[i]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: