noi 2007 项链工厂 线段树
1 #include<iostream> 2 #include<cmath> 3 #include<cstdio> 4 #include<cstring> 5 using namespace std; 6 #define MAXN 500001 7 struct node 8 { 9 int left,right,left_color,right_color,part; 10 bool mark; 11 }tree[4*MAXN]; 12 int color[MAXN]; 13 int rev,delta,n,m,cur_color; 14 void update(int t) 15 { 16 tree[t].left_color=tree[2*t].left_color; 17 tree[t].right_color=tree[2*t+1].right_color; 18 tree[t].part=tree[2*t].part+tree[2*t+1].part-(tree[2*t].right_color==tree[2*t+1].left_color); 19 } 20 void build(int t) 21 { 22 if(tree[t].left==tree[t].right) 23 { 24 tree[t].left_color=tree[t].right_color=color[tree[t].left]; 25 tree[t].part=1; 26 return ; 27 } 28 int mid=(tree[t].left+tree[t].right)/2; 29 tree[2*t].left=tree[t].left; tree[2*t].right=mid; 30 tree[2*t+1].left=mid+1; tree[2*t+1].right=tree[t].right; 31 build(2*t); build(2*t+1); 32 update(t); 33 } 34 void make(int &x,int &y) 35 { 36 if(rev%2==0) 37 { 38 x=(x-delta+n)%n; 39 y=(y-delta+n)%n; 40 } 41 else 42 { 43 x=(2*n+2-delta-x)%n; 44 y=(2*n+2-delta-y)%n; 45 swap(x,y); 46 } 47 if(x==0) 48 x=n; 49 if(y==0) 50 y=n; 51 } 52 void push_down(int t) 53 { 54 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; 55 tree[2*t].part=tree[2*t+1].part=1; 56 tree[2*t].mark=tree[2*t+1].mark=1; 57 tree[t].mark=0; 58 } 59 void change(int t,int x,int y,int c) 60 { 61 if(tree[t].left==x&&tree[t].right==y) 62 { 63 tree[t].left_color=tree[t].right_color=c; 64 tree[t].part=1; 65 tree[t].mark=1; 66 return ; 67 } 68 if(tree[t].mark==1) 69 push_down(t); 70 int mid=(tree[t].left+tree[t].right)/2; 71 if(y<=mid) 72 change(2*t,x,y,c); 73 else if(x>mid) 74 change(2*t+1,x,y,c); 75 else 76 change(2*t,x,mid,c),change(2*t+1,mid+1,y,c); 77 update(t); 78 } 79 int search(int t,int x,int y) 80 { 81 if(tree[t].left==x&&tree[t].right==y) 82 { 83 cur_color=tree[t].left_color; 84 return tree[t].part; 85 } 86 if(tree[t].mark) 87 push_down(t); 88 int mid=(tree[t].left+tree[t].right)/2; 89 if(y<=mid) 90 return search(2*t,x,y); 91 else if(x>mid) 92 return search(2*t+1,x,y); 93 else 94 return search(2*t,x,mid)+search(2*t+1,mid+1,y)-(tree[2*t].right_color==tree[2*t+1].left_color); 95 } 96 int main() 97 { 98 int x,y,z; 99 char c[10]; 100 int i; 101 int temp1,temp2; 102 rev=delta=0; 103 memset(tree,0,sizeof(tree)); 104 scanf("%d%d",&n,&m); 105 for(i=1;i<=n;i++) 106 scanf("%d",color+i); 107 tree[1].left=1; tree[1].right=n; 108 build(1); 109 scanf("%d",&m); 110 for(i=1;i<=m;i++) 111 { 112 scanf("%s",c); 113 if(c[0]=='R') 114 { 115 scanf("%d",&x); 116 if(rev%2==0) 117 delta=(delta+x)%n; 118 else 119 delta=(delta-x+n)%n; 120 } 121 if(c[0]=='F') 122 rev++; 123 if(c[0]=='S') 124 { 125 scanf("%d%d",&x,&y); 126 make(x,y); 127 search(1,x,x); temp1=cur_color; 128 search(1,y,y); temp2=cur_color; 129 change(1,x,x,temp2); 130 change(1,y,y,temp1); 131 } 132 if(c[0]=='P') 133 { 134 scanf("%d%d%d",&x,&y,&z); 135 make(x,y); 136 if(x<=y) 137 change(1,x,y,z); 138 else 139 { 140 change(1,x,n,z); 141 change(1,1,y,z); 142 } 143 } 144 if(c[0]=='C'&&c[1]!='S') 145 { 146 int ans=search(1,1,n); 147 search(1,1,1); temp1=cur_color; 148 search(1,n,n); temp2=cur_color; 149 if(temp1==temp2) 150 ans=max(ans-1,1); 151 printf("%d\n",ans); 152 } 153 if(c[0]=='C'&&c[1]=='S') 154 { 155 scanf("%d%d",&x,&y); 156 make(x,y); 157 //cout<<x<<" "<<y<<endl; 158 if(x<=y) 159 printf("%d\n",search(1,x,y)); 160 else 161 { 162 int ans=search(1,x,n)+search(1,1,y); 163 search(1,1,1); temp1=cur_color; 164 search(1,n,n); temp2=cur_color; 165 if(temp1==temp2) 166 ans=ans-1; 167 printf("%d\n",ans); 168 } 169 } 170 } 171 return 0; 172 } 173 174