1493: [NOI2007]項鍊工廠
Time Limit: 30 Sec Memory Limit: 64 MB[Submit][Status][Discuss]
Description
Input
Output
對於每一個 C 和 CS 命令,應輸出一個整數代表相應的答案。
Sample Input
1 2 3 2 1
4
C
R 2
P 5 5 2
CS 4 1
Sample Output
1
HINT
Source
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
int delta=0,rev=0,n,c,a[N],q; char opt[5];
int flag[N<<2],sum[N<<2],lc[N<<2],rc[N<<2];
void update( int k ){
lc[k] = lc[k<<1]; rc[k] = rc[k<<1|1];
if( rc[k<<1] == lc[k<<1|1] ) sum[k] = sum[k<<1] + sum[k<<1|1] - 1;
else sum[k] = sum[k<<1] + sum[k<<1|1];
}
void pushdown( int k ){
if( flag[k] != -1 ){
lc[k<<1] = lc[k<<1|1] = rc[k<<1] = rc[k<<1|1] = flag[k];
flag[k<<1] = flag[k<<1|1] = flag[k];
sum[k<<1] = sum[k<<1|1] = 1; flag[k] = -1;
}
}
void build( int k, int l, int r ){
flag[k] = -1;
if( l == r ){
lc[k] = rc[k] = a[l];
sum[k] = 1;
return ;
}
int mid = l + r >> 1;
build( k<<1, l, mid );
build( k<<1|1, mid+1, r );
update( k );
}
void change( int k, int l, int r, int L, int R, int val ){
if( L <= l && r <= R ){
flag[k] = val; sum[k] = 1; lc[k] = rc[k] = val;
return ;
}
int mid = l + r >> 1;
pushdown( k );
if( L <= mid ) change( k<<1, l, mid, L, R, val );
if( R > mid ) change( k<<1|1, mid+1, r, L, R, val );
update( k );
}
int query( int k, int l, int r, int L, int R ){
if( L <= l && r <= R ) return sum[k];
int mid = l + r >> 1, ret = 0, lsr = 0, rsl = 0;
pushdown( k );
if( L <= mid ) ret += query( k<<1, l, mid, L, R ), lsr = rc[k<<1];
if( R > mid ) ret += query( k<<1|1, mid+1, r, L, R ), rsl = lc[k<<1|1];
if( lsr && rsl && lsr == rsl ) ret--;
update( k );
return ret;
}
int query( int k, int l, int r, int x ){
if( l == r ) return lc[k];
int mid = l + r >> 1, res;
pushdown( k );
if( x <= mid ) res = query( k<<1, l, mid, x );
else res = query( k<<1|1, mid+1, r, x );
update(k);
return res;
}
void change( int &l, int &r ){
if( rev ){
l = ( 2 * n + 2 - l - delta ) % n;
r = ( 2 * n + 2 - r - delta ) % n;
swap( l, r );
}else{
l = ( l + n - delta ) % n;
r = ( r + n - delta ) % n;
}
l = l ? l : n; r = r ? r : n;
}
int main(){
scanf( "%d%d", &n, &c );
for( int i = 1; i <= n; i++ ) scanf( "%d", &a[i] );
build( 1, 1, n ); scanf( "%d", &q );
while( q-- ){
scanf( "%s", opt ); int len = strlen(opt);
if( opt[0] == 'R' ){
int k;
scanf( "%d", &k );
if( rev ) delta = ( delta + n - k ) % n;
else delta = ( delta + k ) % n;
}
if( opt[0] == 'F' ) rev ^= 1;
if( opt[0] == 'S' ){
int l, r, x, y;
scanf( "%d%d", &l, &r );
change( l, r );
x = query( 1, 1, n, l );
y = query( 1, 1, n, r );
change( 1, 1, n, l, l, y );
change( 1, 1, n, r, r, x );
}
if( opt[0] == 'P' ){
int l, r, x;
scanf( "%d%d%d", &l, &r, &x );
change( l, r );
if( l <= r ) change( 1, 1, n, l, r, x );
else change( 1, 1, n, 1, r, x ), change( 1, 1, n, l, n, x );
}
if( opt[0] == 'C' && len == 1 ){
int ret = query( 1, 1, n, 1, n );
// printf( "%d %d\n", query( 1, 1, n, 1 ), query( 1, 1, n, n ) );
if( query( 1, 1, n, 1 ) == query( 1, 1, n, n ) && ret != 1 ) ret--;
printf( "%d\n", ret );
}
if( len == 2 ){
int l, r;
scanf( "%d%d", &l, &r );
change( l, r );
if( l <= r ){
if( l == 1 && r == n ){
int ret = query( 1, 1, n, 1, n );
if( query( 1, 1, n, 1 ) == query( 1, 1, n, n ) && ret != 1 ) ret--;
printf( "%d\n", ret );
}else{
printf( "%d\n", query( 1, 1, n, l, r ) );
}
}else{
int ret = query( 1, 1, n, 1, r ) + query( 1, 1, n, l, n );
if( query( 1, 1, n, 1 ) == query( 1, 1, n, n ) ) ret--;
printf( "%d\n", ret );
}
}
}
return 0;
}/*
5 3
1 2 3 2 1
5
C
F
R 2
P 5 5 2
CS 4 1
*/