标签:bit div pac end c++ r++ sdi operator read
(带修莫队题....有点卡常需要调整块的大小....最合适的位置为sz=(n^(2/3)),可通过基本不等式证明,(明天补树套树做法
题解:权值很小,数组可解决(权值过大应该考虑离散化),然后就是基本带修操作
#include <bits/stdc++.h>
#define ll long long
#define s second
#define f first
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
const int MAXN=5e4+10;
const int NM=1e6+100;
using namespace std;
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-‘0‘,ch=getchar();
return f*x;
}
int n,m;
int a[MAXN],b[MAXN];
typedef struct node{
int pos,x,y;
}node;
node d1[MAXN],d2[MAXN];
int p[MAXN],flag[NM];
typedef struct Node{
int l,r,t,id;
friend bool operator<(Node aa,Node bb){
if(p[aa.l]==p[bb.l]&&p[aa.r]==p[bb.r]) return aa.t<bb.t;
else if(p[aa.l]==p[bb.l]) return p[aa.r]<p[bb.r];
else return p[aa.l]<p[bb.l];
}
}Node;
Node que[MAXN];
int ans[MAXN],ans1;
void join(int l,int r,int pos){
if(l<=d1[pos].pos&&d1[pos].pos<=r){
flag[d1[pos].x]--;
if(!flag[d1[pos].x])ans1--;
flag[d1[pos].y]++;
if(flag[d1[pos].y]==1)ans1++;
}
a[d1[pos].pos]=d1[pos].y;
}
void erase(int l,int r,int pos){
if(l<=d2[pos].pos&&d2[pos].pos<=r){
flag[d2[pos].x]--;
if(!flag[d2[pos].x])ans1--;
flag[d2[pos].y]++;
if(flag[d2[pos].y]==1)ans1++;
}
a[d2[pos].pos]=d2[pos].y;
}
int main(){
n=read(),m=read();int sz=(int)pow(n,2.0/3);
for(int i=1;i<=n;i++)p[i]=(i-1)/sz+1;
inc(i,1,n)a[i]=read(),b[i]=a[i];
int t=0,pos,vul;char ch;int cnt=0;
for(int i=1;i<=m;i++){
scanf(" %c",&ch);
if(ch==‘Q‘){
que[++cnt].l=read();que[cnt].r=read();que[cnt].id=i;que[cnt].t=t;
}
else{
t++;pos=read(),vul=read();
d1[t].pos=pos;d1[t].x=b[pos];d1[t].y=vul;
d2[t].pos=pos;d2[t].x=vul;d2[t].y=b[pos];
b[pos]=vul;
}
ans[i]=-1;
}
sort(que+1,que+cnt+1);
int L=1,R=0,T=0;ans1=0;
for(int i=1;i<=cnt;i++){
while(que[i].t<T){
erase(L,R,T);T--;
}
while(que[i].t>T){
T++;join(L,R,T);
}
while(que[i].l>L){
flag[a[L]]--;
if(!flag[a[L]])ans1--;
L++;
}
while(que[i].l<L){
L--;flag[a[L]]++;
if(flag[a[L]]==1)ans1++;
}
while(que[i].r<R){
flag[a[R]]--;
if(!flag[a[R]])ans1--;
R--;
}
while(que[i].r>R){
R++;flag[a[R]]++;
if(flag[a[R]]==1)ans1++;
}
ans[que[i].id]=ans1;
}
for(int i=1;i<=m;i++)if(ans[i]>=0)printf("%d\n",ans[i]);
return 0;
}
标签:bit div pac end c++ r++ sdi operator read
原文地址:https://www.cnblogs.com/wang9897/p/9049010.html