bzoj1493: [NOI2007]项链工厂
来源:互联网 发布:电视机怎么看网络电视 编辑:程序博客网 时间:2024/06/10 03:49
传送门
能不用splay坚决不用splay—–zyy
这道题如果没有旋转翻转操作的话就是一道区间修改,区间查询的线段树水题。
那么对于R,F操作应该怎么处理呢?
其实R,F操作之后珠子的相对位置没变
通俗来说就是一个珠子左右两边的珠子还是原来那两个
所以对于R,F操作我们只需要分别记录两个量即可:mov,rev
1.mov:表示当前整体顺时针移动了mov(即k变成k+mov)
输入R k,分两种情况:
没有被翻转过,mov+=k;
被翻转过,mov-=k
2.rev:表示当前是否被翻转过
输入F,直接rev^=1
然后线段树就水过了。
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<cstdlib>#define ls x*2#define rs x*2+1using namespace std;struct node{int l,r,tag,lc,rc,sum;}t[2000005];int n,cnt,m,x,y,z,ans,rev=0,mov=0,co[500005];char ch[10];void get(int &a){ if (rev) a=n-a+2; a-=mov; for (;a>n;a-=n); for (;a<1;a+=n);}void pushup(int x){ t[x].lc=t[ls].lc; t[x].rc=t[rs].rc; t[x].sum=t[ls].sum+t[rs].sum; if (t[ls].rc==t[rs].lc) t[x].sum--;}void pushdown(int x){ if (!t[x].tag) return; t[ls].tag=t[rs].tag=t[x].tag; t[ls].lc=t[ls].rc=t[rs].lc=t[rs].rc=t[x].tag; t[ls].sum=t[rs].sum=1; t[x].tag=0;}node merge(node a,node b){ node tmp; tmp.sum=a.sum+b.sum; tmp.lc=a.lc; tmp.rc=b.rc; if (a.rc==b.lc) tmp.sum--; return tmp;}void build(int x,int l,int r){ t[x].l=l; t[x].r=r; t[x].tag=0; if (l==r){ t[x].lc=t[x].rc=t[x].tag=co[l]; t[x].sum=1; return; } int mid=(l+r)/2; build(ls,l,mid); build(rs,mid+1,r); pushup(x);}int color(int x,int y){ int l=t[x].l,r=t[x].r,mid=(l+r)/2; if (l==r) return t[x].lc; pushdown(x); if (y<=mid) return color(ls,y); return color(rs,y);}void change(int x,int p,int q,int v){ int l=t[x].l,r=t[x].r,mid=(l+r)/2; if (l==p&&r==q){ t[x].lc=t[x].rc=t[x].tag=v; t[x].sum=1; return; } pushdown(x); if (q<=mid) change(ls,p,q,v); else if (p>mid) change(rs,p,q,v); else change(ls,p,mid,v),change(rs,mid+1,q,v); pushup(x);}node ask(int x,int p,int q){ int l=t[x].l,r=t[x].r,mid=(l+r)/2; if (l==p&&r==q) return t[x]; pushdown(x); if (q<=mid) return ask(ls,p,q); if (p>mid) return ask(rs,p,q); return merge(ask(ls,p,mid),ask(rs,mid+1,q));}int main(){ scanf("%d%d",&n,&cnt); for (int i=1;i<=n;i++) scanf("%d",&co[i]); build(1,1,n); scanf("%d",&m); while (m--){ scanf("%s",ch); if (ch[0]=='R'){ scanf("%d",&x); if (rev) mov-=x; else mov+=x; for (;mov>n;mov-=n); for (;mov<0;mov+=n); } if (ch[0]=='F') rev^=1; if (ch[0]=='S'){ scanf("%d%d",&x,&y); get(x); get(y); int xx=color(1,x),yy=color(1,y); change(1,x,x,yy); change(1,y,y,xx); } if (ch[0]=='P'){ scanf("%d%d%d",&x,&y,&z); get(x); get(y); if (rev) swap(x,y); if (x>y) change(1,x,n,z),change(1,1,y,z); else change(1,x,y,z); } if (ch[0]=='C'){ if (ch[1]=='S'){ scanf("%d%d",&x,&y); get(x); get(y); if (rev) swap(x,y); if (x<=y){ ans=ask(1,x,y).sum; if (x==1&&y==n&&ans>1&&t[1].lc==t[1].rc) ans--; } else{ ans=ask(1,x,n).sum+ask(1,1,y).sum; if (t[1].lc==t[1].rc) ans--; } } else{ ans=t[1].sum; if (ans>1&&t[1].lc==t[1].rc) ans--; } printf("%d\n",ans); } }}
0 0
- [BZOJ1493][NOI2007]项链工厂
- bzoj1493: [NOI2007]项链工厂
- bzoj1493: [NOI2007]项链工厂 splay
- BZOJ1493: [NOI2007]项链工厂 Splay
- [题解]bzoj1493 NOI2007项链工厂
- [BZOJ1493][NOI2007]项链工厂(splay)
- [bzoj1493]1493: [NOI2007]项链工厂 线段树
- 【bzoj1493】项链工厂【线段树】
- 1493: [NOI2007]项链工厂
- 【线段树】【NOI2007】项链工厂
- 【BZOJ 1493】[NOI2007]项链工厂
- 【BZOJ】1493 [NOI2007]项链工厂 线段树
- BZOJ 1493 NOI2007 项链工厂 Splay
- 【BZOJ】【P1493】【NOI2007】【项链工厂】【题解】【Treap】
- [NOI2007]项链工厂(线段树)
- bzoj 1493 [NOI2007]项链工厂 线段树
- [BZOJ]1493 [NOI2007]项链工厂 线段树
- bzoj 1493: [NOI2007]项链工厂 (平衡树)
- 站在风口的猪也会飞,背后推手是谁?
- docker容器启动后修改启动命令参数
- Node.js模块小记之--util
- Mysql 函数
- tensorflow学习笔记(三十九):双向rnn
- bzoj1493: [NOI2007]项链工厂
- JavaScript语言基础---(十)Date
- MySQL 优化
- Codeforces 682D Alyona and Strings DP
- 集合框架-模拟斗地主洗牌和发牌案例
- Tomacat部署两个项目的几点经验
- zabbix集成110OneAlert报警
- 使用ThinkAndroid数据库及解决造成ANR问题
- 【java开发系列】—— 自定义注解