莫队后三个点过了求助
查看原帖
莫队后三个点过了求助
107527
chenkaiwen楼主2021/11/14 22:35

先按照自己的想法写了一遍,结果只有后三个点过来,然后看完题解后又重新按照题解写了一遍,结果还是只有后三个点过了,求助

自己的思路

#include<bits/stdc++.h>
using namespace std;
struct as{
	int l,r,id;
	int ans;
}e[140000];
int n,m;
int color[140000],k[140000];
bool cmp(as a,as b){
	return k[a.l]!=k[b.l]?k[a.l]<k[b.l]:k[a.r]!=k[b.r]?k[a.r]<k[b.r]:a.l!=b.l?a.l<b.l:a.r<b.r;
}
bool cmp2(as a,as b){
	return a.id<b.id;
}
int s=1,t=1;
long long sum[1000000],xum=0;
void dosth(){
	if(t<s)return;
	sort(e+s,e+t+1,cmp);
	for(int i=1;i<=n;i++)sum[i]=0;
	xum=0;
	int l=e[s].l,r=e[s].r;
	for(int i=l;i<=r;i++)xum+=(!sum[color[i]])?1:0,sum[color[i]]++;
	e[s].ans=xum;
	for(int i=s+1;i<=t;i++){
		while(l<e[i].l)sum[color[l]]--,xum-=(!sum[color[l++]])?1:0;
		while(l>e[i].l)xum+=(!sum[color[--l]])?1:0,sum[color[l]]++;
		while(r<e[i].r)xum+=(!sum[color[++r]])?1:0,sum[color[r]]++;
		while(r>e[i].r)sum[color[r]]--,xum-=(!sum[color[r--]])?1:0;
		e[i].ans=xum;
	}
}
void In(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&color[i]);
		k[i]=(i-1)/((int)(sqrt(n)))+1;
	}
}
void Work(){
	int cnt=0;
	for(int i=1;i<=m;i++){
		string t1;int t2,t3;
		cin>>t1>>t2>>t3;
		if(t1[0]=='Q'){
			e[++cnt].l=t2,e[cnt].r=t3,e[cnt].id=i;
			t=cnt;
		}else{
			dosth();
			s=cnt+1;
			color[t2]=t3;
		}
	}
	dosth();
	sort(e+1,e+cnt+1,cmp2);
	for(int i=1;i<=cnt;i++){
		printf("%d\n",e[i].ans);
	}
}
int main(){
	In();
	Work();
	return 0;
}

题解思路

#include<bits/stdc++.h>
using namespace std;
struct as{
	int l,r,id,time;
	int ans;
}e[140000];
struct cs{
	int ip,c;
}c[140000];
int n,m;
int color[140000],k[140000];
bool cmp(as a,as b){
	return k[a.l]!=k[b.l]?k[a.l]<k[b.l]:k[a.r]!=k[b.r]?k[a.r]<k[b.r]:a.l!=b.l?a.l<b.l:a.r<b.r;
}
bool cmp2(as a,as b){
	return a.id<b.id;
}
long long sum[1000000],xum=0;
void In(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&color[i]);
		k[i]=(i-1)/((int)(sqrt(n)))+1;
	}
}
void Work(){
	int cnt=0,tot=0;
	for(int i=1;i<=m;i++){
		string t1;int t2,t3;
		cin>>t1>>t2>>t3;
		if(t1[0]=='Q'){
			e[++cnt].l=t2,e[cnt].r=t3,e[cnt].id=i,e[cnt].time=tot;
		}else{
			c[++tot].ip=t2,c[tot].c=t3;
		}
	}
	sort(e+1,e+cnt+1,cmp);
	xum=0;
	int l=e[1].l,r=e[1].r,nt=0;
	for(int i=l;i<=r;i++)xum+=(!sum[color[i]])?1:0,sum[color[i]]++;
	e[1].ans=xum;
	for(int i=1;i<=cnt;i++){
		while(l<e[i].l)sum[color[l]]--,xum-=(!sum[color[l++]])?1:0;
		while(l>e[i].l)xum+=(!sum[color[--l]])?1:0,sum[color[l]]++;
		while(r<e[i].r)xum+=(!sum[color[++r]])?1:0,sum[color[r]]++;
		while(r>e[i].r)sum[color[r]]--,xum-=(!sum[color[r--]])?1:0;
		while(nt>e[i].time){if(c[nt].ip<=e[i].r&&c[nt].ip>=e[i].l)xum+=(!sum[c[nt].c]++?1:0),xum-=(!(--sum[color[c[nt].ip]])?1:0),swap(color[c[nt].ip],c[nt].c);nt--;}
		while(nt<e[i].time){++nt;if(c[nt].ip<=e[i].r&&c[nt].ip>=e[i].l)xum+=(!sum[c[nt].c]++?1:0),xum-=(!(--sum[color[c[nt].ip]])?1:0),swap(color[c[nt].ip],c[nt].c);}
		e[i].ans=xum;
	}
	sort(e+1,e+cnt+1,cmp2);
	for(int i=1;i<=cnt;i++){
		printf("%d\n",e[i].ans);
	}
}
int main(){
	In();
	Work();
	return 0;
}
/*
6 5
1 2 3 4 5 5
 Q 1 4
 Q 2 6
 R 1 2
 Q 1 4
 Q 2 6
*/
2021/11/14 22:35
加载中...