[bzoj1493]1493: [NOI2007]项链工厂 线段树
2017-09-28 20:15
267 查看
1493: [NOI2007]项链工厂
Time Limit: 30 Sec Memory Limit: 64 MB[Submit][Status][Discuss]
Description
T公司是一家专门生产彩色珠子项链的公司,其生产的项链设计新颖、款式多样、价格适中,广受青年人的喜爱。最近T公司打算推出一款项链自助生产系统,使用该系统顾客可以自行设计心目中的美丽项链。该项链自助生产系
统包括硬件系统与软件系统,软件系统与用户进行交互并控制硬件系统,硬件系统接受软件系统的命令生产指定的
项链。该系统的硬件系统已经完成,而软件系统尚未开发,T公司的人找到了正在参加全国信息学竞赛的你,你能
帮助T公司编写一个软件模拟系统吗?一条项链包含 N 个珠子,每个珠子的颜色是 1,2,…,c 中的一种。项链
被固定在一个平板上,平板的某个位置被标记位置 1 ,按顺时针方向其他位置被记为 2,3,…,N。
你将要编写的软件系统应支持如下命令:
Input
输入文件第一行包含两个整数 N,c ,分别表示项链包含的珠子数目以及颜色数目。第二行包含 N 个整数,x1,x2,…,xn ,表示从位置 1 到位置 N 的珠子的颜色,1≤xi≤c 。
第三行包含一个整数 Q ,表示命令数目。接下来的 Q 行每行一条命令,如上文所述。N≤500000 ,Q≤500000,c≤1000
Output
对于每一个 C 和 CS 命令,应输出一个整数代表相应的答案。Sample Input
5 31 2 3 2 1
4
C
R 2
P 5 5 2
CS 4 1
Sample Output
41
HINT
注意旋转命令旋转“珠子”但不改变“位置”的编号,而反转命令始终以位置 1 为对称轴。例如当 N=10 时,项链上的位置编号如图1:
但注意此时项链上的位置编号仍然如图1所示,于是翻转的对称轴不变。因而再执行一次“F”命令时,项链的颜色
如图4所示。
2. 关于CountSegment命令CS命令表示查询一个“线段”中有多少个“部分”。尤其注意当查询的长度
等于 N 时,我们仍然将查询部分作为“线段”理解。例如在图4所示的情况中,执行“CS 1 10”命令,查询从位
置 1 开始到位置 10 结束的这个长度为 10 的线段中有多少个“部分”,于是得到返回值 3 。与之形成对照的是
,若执行“C”命令,返回值则为 2
Source
主要是处理坐标比较恶心线段树部分灰常简单
就是个裸线段树还考处理坐标
样例数据操作还不全
关键是我第一次写完时还把线段树写错了,真是个智障
此题我又一次自带大常数
#include <bits/stdc++.h> using namespace std; const int N = 5e5 + 5; int delta=0,rev=0,n,c,a ,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 */
相关文章推荐
- bzoj1493[NOI2007]项链工厂 线段树
- bzoj 1493: [NOI2007]项链工厂(线段树)
- [BZOJ]1493 [NOI2007]项链工厂 线段树
- 【BZOJ】1493 [NOI2007]项链工厂 线段树
- bzoj 1493 [NOI2007]项链工厂 线段树
- 【bzoj1493】项链工厂【线段树】
- bzoj1493: [NOI2007]项链工厂 splay
- bzoj1493 [NOI2007]项链工厂(splay)
- BZOJ1493: [NOI2007]项链工厂 Splay
- BZOJ1493 : [NOI2007]项链工厂
- [BZOJ1493][NOI2007]项链工厂
- bzoj 1493: [NOI2007]项链工厂 (平衡树)
- 【BZOJ1493】项链工厂(线段树)
- 【BZOJ1493】项链工厂(线段树)
- [bzoj1493] [NOI2007]项链工厂
- BZOJ 1493 NOI2007 项链工厂 Splay
- bzoj1493: [NOI2007]项链工厂
- BZOJ1493 NOI2007 项链工厂 线段树模拟
- [BZOJ1493][NOI2007]项链工厂(splay)
- BZOJ_1493_[NOI2007]项链工厂_Splay