线段树WA0pts求调玄关
查看原帖
线段树WA0pts求调玄关
670978
Arc0_FishyFool楼主2025/7/22 20:48
#include <bits/stdc++.h>
using namespace std;
int coltag[1919810<<2],a[1919810],n,c,len[1919810<<2],q,hd=1,dir=1;
struct SegTree{
	int prt,lcol,rcol;
	SegTree(int prt=0,int lcol=0,int rcol=0):
	prt(prt),lcol(lcol),rcol(rcol){}
}t[1919810<<2];
SegTree pushup(SegTree lson,SegTree rson){
	return SegTree(((lson.rcol==rson.lcol&&lson.rcol)?lson.prt+rson.prt-1:lson.prt+rson.prt),lson.lcol,rson.rcol);
}
inline void tag(int x,int col){
	coltag[x]=col;
	t[x]=SegTree(1,col,col);
}
void pushdown(int x){
	if(coltag[x]){
		tag(x<<1,coltag[x]);
		tag(x<<1|1,coltag[x]);
		coltag[x]=0;
	}
}
void build(int x,int l,int r){
	len[x]=r-l+1;
	if(l==r){
		t[x]=SegTree(1,a[l],a[l]);
		return;
	}
	int mid=(l+r)>>1;
	build(x<<1,l,mid);
	build(x<<1|1,mid+1,r);
	t[x]=pushup(t[x<<1],t[x<<1|1]);
}
int findcol(int x,int l,int r,int pos){
	if(l==r&&l==pos) return t[x].lcol;
	pushdown(x);
	int mid=(l+r)>>1;
	if(mid>=pos) return findcol(x<<1,l,mid,pos);
	else return findcol(x<<1|1,mid+1,r,pos);
}
void flatten(int x,int l,int r,int L,int R,int col){
	if(L<=l&&r<=R){
		tag(x,col);
		return;
	}
	pushdown(x);
	int mid=(l+r)>>1;
	if(L<=mid) flatten(x<<1,l,mid,L,R,col);
	if(R>mid) flatten(x<<1|1,mid+1,r,L,R,col);
	t[x]=pushup(t[x<<1],t[x<<1|1]);
}
SegTree query(int x,int l,int r,int L,int R){
	if(L<=l&&r<=R){
		return t[x];
	}
	pushdown(x);
	SegTree r1,r2,res;
	r1=r2=SegTree();
	int mid=(l+r)>>1;
	if(L<=mid) r1=query(x<<1,l,mid,L,R);
	if(R>mid) r2=query(x<<1|1,mid+1,r,L,R);
	res=pushup(r1,r2);
	return res;
}
int main(){
	scanf("%d%d",&n,&c);
	for(int i=1;i<=n;++i){
		scanf("%d",a+i);
		a[i+n]=a[i];
	}
	int N=2*n;
	build(1,1,N);
	scanf("%d",&q);
	while(q--){
		string opt;
		int i,j,x;
		cin>>opt;
		if(opt[0]=='R'){
			scanf("%d",&i);
			hd=((hd-1-dir*i)%n+n)%n+1;
		}
		else if(opt[0]=='F'){
			dir=-dir;
		}
		else if(opt=="C"){
			SegTree ans=query(1,1,N,1,N);
			printf("%d\n",ans.prt/2);
		}
		else{
			bool flag=false;
			int _i,_j;
			scanf("%d%d",&i,&j);
			i=((hd-1+dir*(i-1))%n+n)%n+1;
			j=((hd-1+dir*(j-1))%n+n)%n+1;
			if(i>j){
				flag=true;
				_j=j;
				j+=n;
				_i=i+n;
			}
			else{
				_j=j+n;
				_i=i+n;
			}
			if(opt[0]=='S'){
				int coli=findcol(1,1,N,i),colj=findcol(1,1,N,j);
				flatten(1,1,N,i,i,colj);
				flatten(1,1,N,_i,_i,colj);
				flatten(1,1,N,j,j,coli);
				flatten(1,1,N,_j,_j,coli);
			}
			else if(opt[0]=='P'){
				scanf("%d",&x);
				flatten(1,1,N,i,j,x);
				if(flag){
					flatten(1,1,N,1,_j,x);
					flatten(1,1,N,_i,N,x);
				}
				else flatten(1,1,N,_i,_j,x);
			}
			else{
				SegTree ans=query(1,1,N,i,j);
				printf("%d\n",ans.prt);
			}
		}
	}
	return 0;
}

思路:dir表示方向,hd表示顶点,用2n的数组存环,则环的总份数为2n数组的部份数/2,处理i,j使i<j且在数组上代表相同点的地方做等价操作,写法参考P2572最上方的题解。

2025/7/22 20:48
加载中...