BZOJ 1493 NOI 2007 项链工厂 Splay
来源:互联网 发布:youtube免费翻墙软件 编辑:程序博客网 时间:2024/05/16 18:26
题目大意:有一个很长的带颜色的项链,要求你快速的维护一种数据结构,他可以:
1.把序列的后k个放在前面。
2.将区间2~cnt的珠子翻转。
3.将位置i和位置j的珠子互换。
4.将区间i到j染色成k
5.输出整个序列的颜色块的个数
6.输出从i到j的颜色块的个数。
思路:Splay。有些不好处理的是要时刻想着这是一个环,所以所有的计算颜色块的个数的时候要考虑收尾的颜色是否相同。还有从序列的尾部到转一圈回去的情况。
就因为这个题我的代码有个小小小小的问题,花了仨小时的时间带着数据才把错找到。。简直不知道说些什么好。。啊啊啊啊以后写题一定要细致啊!!!
CODE:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAX 500010using namespace std;struct Complex{int col,cnt_col,l_col,r_col;int size;Complex *son[2],*father;bool reverse,change;int change_into;void Combine(Complex *a,bool dir) {son[dir] = a;a->father = this;}bool Check() {return father->son[1] == this;}void Reverse();void Paint(int val);void PushUp();void PushDown();}*nil = new Complex(),*root;int cnt,cols,asks;int src[MAX];char cmd[10];void Pretreatment();inline Complex *NewComplex(int val);Complex *BuildTree(int l,int r);Complex *Kth(Complex *a,int k);inline void Rotate(Complex *a,bool dir);inline void Splay(Complex *a,Complex *aim);inline void SplaySeg(int x,int y);int main(){Pretreatment();cin >> cnt >> asks;for(int i = 1;i <= cnt; ++i)scanf("%d",&src[i]);root = BuildTree(0,cnt + 1);root->father = nil;cin >> asks;for(int x,y,z,i = 1;i <= asks; ++i) {scanf("%s",cmd);if(cmd[0] == 'R') {scanf("%d",&x);SplaySeg(cnt - x + 1,cnt);Complex *temp = root->son[1]->son[0];temp->father = nil;root->son[1]->son[0] = nil;root->son[1]->PushUp(),root->PushUp();Splay(Kth(root,1),nil);Splay(Kth(root,2),root);root->son[1]->Combine(temp,false);}else if(cmd[0] == 'F') {SplaySeg(2,cnt);root->son[1]->son[0]->Reverse();}else if(cmd[0] == 'S') {scanf("%d%d",&x,&y);if(x == y)continue;if(x > y)swap(x,y);Splay(Kth(root,x + 1),nil);Splay(Kth(root,y + 1),root);int temp = root->son[1]->col;root->son[1]->col = root->col;root->son[1]->PushUp(),root->PushUp();root->col = temp;}else if(cmd[0] == 'P') {scanf("%d%d%d",&x,&y,&z);if(y >= x) {SplaySeg(x,y);root->son[1]->son[0]->Paint(z);}else {SplaySeg(x,cnt);root->son[1]->son[0]->Paint(z);root->son[1]->PushUp(),root->PushUp();SplaySeg(1,y);root->son[1]->son[0]->Paint(z);}}else if(cmd[0] == 'C' && cmd[1] == '\0') {SplaySeg(1,cnt);int ans = root->son[1]->son[0]->cnt_col;ans -= (root->son[1]->son[0]->l_col == root->son[1]->son[0]->r_col);if(!ans)++ans;printf("%d\n",ans);continue;}else {scanf("%d%d",&x,&y);if(y >= x) {SplaySeg(x,y);printf("%d\n",root->son[1]->son[0]->cnt_col);}else {int ans = 0;SplaySeg(x,cnt);ans = root->son[1]->son[0]->cnt_col;SplaySeg(1,y);ans += root->son[1]->son[0]->cnt_col;SplaySeg(1,cnt);ans -= (root->son[1]->son[0]->l_col == root->son[1]->son[0]->r_col);printf("%d\n",ans);}continue;}root->son[1]->PushUp(),root->PushUp();}return 0;}void Complex:: Reverse() {if(!col)return ;reverse ^= 1;swap(son[0],son[1]);swap(l_col,r_col);}void Complex:: Paint(int val) {if(!col)return ;change = true;change_into = val;l_col = r_col = col = val;cnt_col = 1;}void Complex:: PushUp() {if(this == nil)return ;size = son[0]->size + son[1]->size + 1;if(!col)return ;cnt_col = 1;l_col = r_col = col;if(son[0]->col) {cnt_col += son[0]->cnt_col - (son[0]->r_col == col);l_col = son[0]->l_col;}if(son[1]->col) {cnt_col += son[1]->cnt_col - (son[1]->l_col == col);r_col = son[1]->r_col;}}void Complex:: PushDown() {if(this == nil)return ;if(reverse) {son[0]->Reverse();son[1]->Reverse();reverse = false;}if(change) {son[0]->Paint(change_into);son[1]->Paint(change_into);change = false;}}void Pretreatment() {nil->size = 0;nil->col = nil->l_col = nil->r_col = 0;nil->cnt_col = 0;nil->father = nil->son[0] = nil->son[1] = nil;}inline Complex *NewComplex(int val){Complex *re = new Complex();re->col = re->l_col = re->r_col = val;re->size = 1;if(val) re->cnt_col = 1;re->son[0] = re->son[1] = nil;return re;}Complex *BuildTree(int l,int r){if(l > r)return nil;int mid = (l + r) >> 1;Complex *re = NewComplex(src[mid]);re->Combine(BuildTree(l,mid - 1),false);re->Combine(BuildTree(mid + 1,r),true);re->PushUp();return re;}Complex *Kth(Complex *a,int k){a->PushDown();if(a->son[0]->size >= k)return Kth(a->son[0],k);k -= a->son[0]->size;if(k == 1)return a;return Kth(a->son[1],k - 1);}inline void Rotate(Complex *a,bool dir){Complex *f = a->father;f->PushDown(),a->PushDown();f->son[!dir] = a->son[dir];f->son[!dir]->father = f;a->son[dir] = f;a->father = f->father;f->father->son[f->Check()] = a;f->father = a;f->PushUp();if(root == f)root = a;}inline void Splay(Complex *a,Complex *aim){while(a->father != aim) {if(a->father->father == aim)Rotate(a,!a->Check());else if(!a->father->Check()) {if(!a->Check())Rotate(a->father,true),Rotate(a,true);elseRotate(a,false),Rotate(a,true);}else {if(a->Check())Rotate(a->father,false),Rotate(a,false);elseRotate(a,true),Rotate(a,false);}}a->PushUp();}inline void SplaySeg(int x,int y){x++,y++;Splay(Kth(root,x - 1),nil);Splay(Kth(root,y + 1),root);}
1 1
- BZOJ 1493 NOI 2007 项链工厂 Splay
- noi 2007 项链工厂 (bzoj 1493)
- noi 2007 项链工厂 (bzoj 1493)
- BZOJ 1493 NOI2007 项链工厂 Splay
- NOI 项链工厂
- 【BZOJ 1493】[NOI2007]项链工厂
- bzoj1493: [NOI2007]项链工厂 splay
- BZOJ1493: [NOI2007]项链工厂 Splay
- 【BZOJ】1493 [NOI2007]项链工厂 线段树
- bzoj 1493 [NOI2007]项链工厂 线段树
- [BZOJ]1493 [NOI2007]项链工厂 线段树
- [BZOJ1493][NOI2007]项链工厂(splay)
- BZOJ 1500 NOI 2005 维修数列 Splay
- BZOJ 1507 NOI 2003 Editor Splay
- BZOJ 1500|NOI 2005|维修数列|Splay
- bzoj 1493: [NOI2007]项链工厂 (平衡树)
- 1493: [NOI2007]项链工厂
- 【BZOJ】【P1493】【NOI2007】【项链工厂】【题解】【Treap】
- SQL SERVER 2005 数据库状态为“可疑”的解决方法
- Sqlite中使用SQL与其他数据库的区别
- leetcode-3Sum
- overridePendingTransition无效果解决方案
- Linux 的多线程编程的高效开发经验
- BZOJ 1493 NOI 2007 项链工厂 Splay
- SAP SD 发票分割 Invoice Split
- java二维码生成与解析代码实现
- 菜鸟版JAVA设计模式—从火锅底料到装饰器模式
- Eclipse Class Decompiler——Java反编译插件
- 2015创发科技校园招聘笔试题——把矩阵顺时针旋转90度
- java序列化
- Cocos2d-x3.1通过JniHelper调用Java类中静态函数
- C++字符串转换(Unicode和ANSI互转)