莫队 3AC+7WA求调

P1903 [国家集训队] 数颜色 / 维护队列

cu求
by _SunLight_ @ 2022-10-06 15:47:57


@[_ChiFAN_](/user/520748) change_old 不一定是a[x]
by xingke233 @ 2022-10-06 16:08:19


@[_ChiFAN_](/user/520748) 我的AC代码(友情注释版): ```cpp #include<bits/stdc++.h> #define E 1e-9 #define INF 0x3f3f3f3f #define LL long long const int MOD=10007; const int N=1000000+5; const int dx[]= {-1,1,0,0}; const int dy[]= {0,0,-1,1}; using namespace std; struct Node{ int l,r;//询问的左右端点 int time;//时间维度 int id;//询问的编号 }q[N]; struct Change{ int pos;//要修改的位置 int col;//要改成的值 }c[N]; int n,m,a[N]; int block;//分块 int numQ,numC;//查询、修改操作的次数 LL ans,cnt[N]; LL res[N]; bool cmp(Node a,Node b){//排序 return (a.l/block)^(b.l/block) ? a.l<b.l : ((a.r/block)^(b.r/block)?a.r<b.r:a.time<b.time); } void add(int x){//统计新的,根据具体情况修改 if(cnt[x]==0) ans++; cnt[x]++; } void del(int x){//减去旧的,根据具体情况修改 cnt[x]--; if(cnt[x]==0) ans--; } void change(int x,int ti){//改变时间轴 if(c[ti].pos>=q[x].l&&c[ti].pos<=q[x].r){ del(a[c[ti].pos]);//删除指定位置上的值 add(c[ti].col);//统计新的数 } swap(c[ti].col,a[c[ti].pos]);//直接互换,下次执行时必定是回退这次操作 } int main(){ while(scanf("%d%d",&n,&m)!=EOF){ ans=0; numQ=0; numC=0; memset(cnt,0,sizeof(cnt)); block=pow(n,0.66666);//分块 for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=m;i++){ char op[10]; scanf("%s",op); if(op[0]=='Q'){//查询操作 ++numQ;//查询操作次数+1 scanf("%d%d",&q[numQ].l,&q[numQ].r); q[numQ].id=numQ;//序号 q[numQ].time=numC;//时间轴 } else{//修改操作 ++numC;//修改操作次数+1 scanf("%d%d",&c[numC].pos,&c[numC].col); } } sort(q+1,q+numQ+1,cmp);//对询问进行排序 int l=1,r=0,time=0;//左右指针与时间轴 for(int i=1;i<=numQ;i++){ int ql=q[i].l,qr=q[i].r;//询问的左右端点 int qtime=q[i].time;//询问的时间轴 while(l>ql) add(a[--l]);//[l-1,r,time] while(l<ql) del(a[l++]);//[l+1,r,time] while(r<qr) add(a[++r]);//[l,r+1,time] while(r>qr) del(a[r--]);//[l,r-1,time] while(time<qtime) change(i,++time);//[l,r,time+1] while(time>qtime) change(i,time--);//[l,r,time-1] res[q[i].id]=ans;//获取答案 } for(int i=1;i<=numQ;i++) printf("%lld\n",res[i]); } return 0; } ```
by luqyou @ 2022-10-06 16:09:49


@[_ChiFAN_](/user/520748) hack ``` 6 5 1 1 9 4 5 5 Q 1 4 Q 2 6 R 1 9 R 1 8 Q 1 6 ```
by xingke233 @ 2022-10-06 16:11:19


@[xingke233](/user/533452) 正确为 ``` 3 4 5 ```
by xingke233 @ 2022-10-06 16:12:51


@[_ChiFAN_](/user/520748) 话说杨吃饭一改不缩进的习惯
by luqyou @ 2022-10-06 16:16:28


@[xingke233](/user/533452) 改了后我的代码还是存在问题
by _SunLight_ @ 2022-10-06 16:19:06


``` //6 5 //1 1 9 4 5 5 //Q 1 4 //Q 2 6 //R 1 9 //R 1 8 //Q 1 6 #include<bits/stdc++.h> using namespace std; int n,m; int a[133334]; struct change{ int old,where,what; }tim[133334]; struct question{ int l,r,t,d; }s[133334]; int l1; int l2; char op; int ans[133334]; int sum; int f[1000001]; int sq; bool cmp(question x,question y) { if(x.l/sq<y.l/sq) return true; if(x.l/sq>y.l/sq) return false; if(x.r<y.r) return true; if(x.r>y.r) return false; if(x.t<y.t) return true; else return false; } void add(int x) { if(f[a[x]]==0) sum++; f[a[x]]++; } void del(int x) { if(f[a[x]]==1) sum--; f[a[x]]--; } void timeadd(int x,int left,int right) { if(tim[x].where>=left&&tim[x].where<=right) { if(f[a[tim[x].where]]==1) sum--; f[a[tim[x].where]]--; if(f[tim[x].what]==0) sum++; f[tim[x].what]++; } a[tim[x].where]=tim[x].what; } void timedel(int x,int left,int right) { if(tim[x].where>=left&&tim[x].where<=right) { if(f[a[tim[x].where]]==1) sum--; f[a[tim[x].where]]--; if(f[tim[x].old]==0) sum++; f[tim[x].old]++; } a[tim[x].where]=tim[x].old; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=m;i++) { scanf("%s",&op); if(op=='Q') { l1++; scanf("%d%d",&s[l1].l,&s[l1].r); s[l1].t=l2; s[l1].d=l1; } else { l2++; scanf("%d%d",&tim[l2].where,&tim[l2].what); tim[l2].old=a[tim[l2].where]; } } sq=sqrt(n); sort(s+1,s+1+l1,cmp); int L=1; int R=0; int T=0; for(int i=1;i<=l1;i++) { while(L<s[i].l)del(L++); while(L>s[i].l)add(--L); while(R<s[i].r)add(++R); while(R>s[i].r)del(R--); while(T>s[i].t)timedel(T--,L,R); while(T<s[i].t)timeadd(++T,L,R); ans[s[i].d]=sum; } for(int i=1;i<=l1;i++) { printf("%d\n",ans[i]); } } ```
by _SunLight_ @ 2022-10-06 16:19:27


@[luqyou](/user/464732)
by _SunLight_ @ 2022-10-06 16:20:55


@[huanghaoxiang27](/user/713562) 不能用old记录,应该直接交换
by xingke233 @ 2022-10-06 16:21:49


| 下一页