您的位置:首页 > 其它

noi 2007 项链工厂 线段树

2012-07-17 21:05 211 查看




#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 500001
struct node
{
int left,right,left_color,right_color,part;
bool mark;
}tree[4*MAXN];
int color[MAXN];
int rev,delta,n,m,cur_color;
void update(int t)
{
tree[t].left_color=tree[2*t].left_color;
tree[t].right_color=tree[2*t+1].right_color;
tree[t].part=tree[2*t].part+tree[2*t+1].part-(tree[2*t].right_color==tree[2*t+1].left_color);
}
void build(int t)
{
if(tree[t].left==tree[t].right)
{
tree[t].left_color=tree[t].right_color=color[tree[t].left];
tree[t].part=1;
return ;
}
int mid=(tree[t].left+tree[t].right)/2;
tree[2*t].left=tree[t].left; tree[2*t].right=mid;
tree[2*t+1].left=mid+1; tree[2*t+1].right=tree[t].right;
build(2*t); build(2*t+1);
update(t);
}
void make(int &x,int &y)
{
if(rev%2==0)
{
x=(x-delta+n)%n;
y=(y-delta+n)%n;
}
else
{
x=(2*n+2-delta-x)%n;
y=(2*n+2-delta-y)%n;
swap(x,y);
}
if(x==0)
x=n;
if(y==0)
y=n;
}
void push_down(int t)
{
tree[2*t].left_color=tree[2*t].right_color=tree[2*t+1].left_color=tree[2*t+1].right_color=tree[t].left_color;
tree[2*t].part=tree[2*t+1].part=1;
tree[2*t].mark=tree[2*t+1].mark=1;
tree[t].mark=0;
}
void change(int t,int x,int y,int c)
{
if(tree[t].left==x&&tree[t].right==y)
{
tree[t].left_color=tree[t].right_color=c;
tree[t].part=1;
tree[t].mark=1;
return ;
}
if(tree[t].mark==1)
push_down(t);
int mid=(tree[t].left+tree[t].right)/2;
if(y<=mid)
change(2*t,x,y,c);
else if(x>mid)
change(2*t+1,x,y,c);
else
change(2*t,x,mid,c),change(2*t+1,mid+1,y,c);
update(t);
}
int search(int t,int x,int y)
{
if(tree[t].left==x&&tree[t].right==y)
{
cur_color=tree[t].left_color;
return tree[t].part;
}
if(tree[t].mark)
push_down(t);
int mid=(tree[t].left+tree[t].right)/2;
if(y<=mid)
return search(2*t,x,y);
else if(x>mid)
return search(2*t+1,x,y);
else
return search(2*t,x,mid)+search(2*t+1,mid+1,y)-(tree[2*t].right_color==tree[2*t+1].left_color);
}
int main()
{
int x,y,z;
char c[10];
int i;
int temp1,temp2;
rev=delta=0;
memset(tree,0,sizeof(tree));
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d",color+i);
tree[1].left=1; tree[1].right=n;
build(1);
scanf("%d",&m);
for(i=1;i<=m;i++)
{
scanf("%s",c);
if(c[0]=='R')
{
scanf("%d",&x);
if(rev%2==0)
delta=(delta+x)%n;
else
delta=(delta-x+n)%n;
}
if(c[0]=='F')
rev++;
if(c[0]=='S')
{
scanf("%d%d",&x,&y);
make(x,y);
search(1,x,x); temp1=cur_color;
search(1,y,y); temp2=cur_color;
change(1,x,x,temp2);
change(1,y,y,temp1);
}
if(c[0]=='P')
{
scanf("%d%d%d",&x,&y,&z);
make(x,y);
if(x<=y)
change(1,x,y,z);
else
{
change(1,x,n,z);
change(1,1,y,z);
}
}
if(c[0]=='C'&&c[1]!='S')
{
int ans=search(1,1,n);
search(1,1,1); temp1=cur_color;
search(1,n,n); temp2=cur_color;
if(temp1==temp2)
ans=max(ans-1,1);
printf("%d\n",ans);
}
if(c[0]=='C'&&c[1]=='S')
{
scanf("%d%d",&x,&y);
make(x,y);
//cout<<x<<" "<<y<<endl;
if(x<=y)
printf("%d\n",search(1,x,y));
else
{
int ans=search(1,x,n)+search(1,1,y);
search(1,1,1); temp1=cur_color;
search(1,n,n); temp2=cur_color;
if(temp1==temp2)
ans=ans-1;
printf("%d\n",ans);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: