求助
查看原帖
求助
701408
lao_wang楼主2024/11/19 14:21

只对的后面3个点,做法是三维偏序,求大佬给一个hack

#include<bits/stdc++.h>
#define N 1123456
#define inf 10000010
#define lowbit(x) ((-x)&(x))
using namespace std ;
int n , q , front[N] , tr[N] , yuan[N] , cnt=0 , num , ans[N] ;
set<int> col[N] ;
struct node{
	int opt , x , k , l , r , i ;
}a[N<<2],q1[N<<2],q2[N<<2];
void change(int x,int k){
	while(x<=n){
		tr[x] += k ;
		x += lowbit(x) ;
	}
}
int ask(int x){
	int ans=0 ;
	while(x){
		ans += tr[x] ;
		x -= lowbit(x) ;
	}
	return ans ;
}
void solve(int l,int r,int L,int R){
	if(l>r||L>R) return ;
	int mid=(l+r)>>1 , tot1=0 , tot2=0 ; 
	for(int i=L;i<=R;i++){
		if(a[i].opt==1){
			if(a[i].x<=mid) change(a[i].i,a[i].k) , q1[++tot1] = a[i] ;
			else q2[++tot2] = a[i] ;
		}else{
			if(a[i].l<=mid) q1[++tot1] = a[i] ;
			else{
				int x=ask(a[i].r)-ask(a[i].l-1) ;
				ans[a[i].i] += x ;
				q2[++tot2] = a[i] ;
			}
		}
	}
	for(int i=1;i<=tot1;i++){
		a[i+L-1] = q1[i] ;
		if(q1[i].opt==1) change(q1[i].i,-q1[i].k) ;
	}
	for(int i=1;i<=tot2;i++) a[i+L-1+tot1] = q2[i] ;
	if(l!=r) solve(l,mid,L,L+tot1-1) ;
	solve(mid+1,r,L+tot1,R) ;
}
int read(){
	int x=0 ;
	char a=getchar() ;
	while(!(a>='0'&&a<='9')){
		a = getchar() ;
	}
	while(a>='0'&&a<='9'){
		x *= 10 ;
		x += a-'0' ;
		a = getchar() ;
	}
	return x ;
}
void write(int x){
	if(x>9) write(x/10) ;
	putchar(x%10+'0') ;
}
signed main(){
	cin >> n >> q ;
	for(int i=1;i<=n;i++){
		yuan[i] = read() ;
		if(col[yuan[i]].empty()) front[i]=0 , col[yuan[i]].insert(inf) , col[yuan[i]].insert(0) ;
		else{
			set<int>::iterator it=col[yuan[i]].lower_bound(i) ;
			it-- ;
			front[i] = *it ;
		}
		col[yuan[i]].insert(i) ;
		a[i].opt = 1 , a[i].i = i , a[i].k = 1 , a[i].x = front[i] ;
	}
	cnt = n ;
	for(int i=1;i<=q;i++){
		char opt ;
		int x , y ;
		cin >> opt ;
		x = read() , y = read() ;
		if(opt=='Q'){
			cnt++ ;
			a[cnt].opt = 2 , a[cnt].i = ++num , a[cnt].l = x , a[cnt].r = y;
		}else{
			cnt++ ;
			a[cnt].opt = 1 , a[cnt].x = front[x] , a[cnt].i = x , a[cnt].k = -1 ;
			set<int>::iterator it=col[yuan[x]].upper_bound(x) ;
			if(*it!=inf) front[*it] = front[x] ;
			col[yuan[x]].erase(x) ;
			yuan[x] = y ;
			if(col[yuan[x]].empty()) col[yuan[x]].insert(inf) , col[yuan[x]].insert(0) ;
			it = col[yuan[x]].upper_bound(x) ;
			if(*it!=inf){
				cnt++ ;
				a[cnt].opt = 1 , a[cnt].x = front[*it] , a[cnt].i = *it , a[cnt].k = -1 ;
				front[*it] = x ;
				cnt++ ;
				a[cnt].opt = 1 , a[cnt].x = front[*it] , a[cnt].i = *it , a[cnt].k = 1 ;
			}
			it-- ;
			front[x] = *it ;
			col[yuan[x]].insert(x) ;
			cnt++ ;
			a[cnt].opt = 1 , a[cnt].x = front[x] , a[cnt].i = x , a[cnt].k = 1 ;
		}
	}
	solve(0,n,1,cnt) ;
	for(int i=1;i<=num;i++) write(ans[i]) , putchar('\n') ;
	return 0 ;
}
2024/11/19 14:21
加载中...