博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 3487 Play with Chain(区间FLIP、CUT)
阅读量:6279 次
发布时间:2019-06-22

本文共 2538 字,大约阅读时间需要 8 分钟。

题目链接:

题意:一个数列两种操作:(1)将一个区间翻转;(2)将一个区间剪下放到另一个位置。

思路:翻转区间[A,B],将A-1,B+1分别调整到根和根节点的右子树;则[A,B]被调整到根节点右子树的左子树,记录翻转标记;剪切时第一步跟翻转一样,第二部将根节点右子树的左子树P剪下,设新插入的位置为C,将C和C+1分别调整到根和根节点的右子树,此时根节点的右子树的左子树为空,将P插在该位置。

int n,m;int c[N][2],p[N],s[N],sign[N];int root;void update(int f,int x,int flag){    p[x]=f;    if(!f) return;    c[f][flag]=x;    s[f]=1+s[c[f][0]]+s[c[f][1]];}void down(int x){    if(!sign[x]) return;    sign[x]=0;    swap(c[x][0],c[x][1]);    sign[c[x][0]]^=1;    sign[c[x][1]]^=1;}void rotate(int x){    int P=p[x],G=p[P];    if(c[P][0]==x)    {        update(P,c[x][1],0);        update(x,P,1);        update(G,x,!(c[G][0]==P));    }    else    {        update(P,c[x][0],1);        update(x,P,0);        update(G,x,!(c[G][0]==P));    }}void splay(int x,int &goal){    int P=p[x],G=p[P],limit=p[goal];    while(P!=limit)    {        if(G!=limit&&(c[G][0]==P)==(c[P][0]==x)) rotate(P);        rotate(x);        P=p[x];        G=p[P];    }    goal=x;    down(goal);}int select(int x){    int t=root;    while(1)    {        down(t);        if(s[c[t][0]]+1==x) break;        if(s[c[t][0]]+1>x) t=c[t][0];        else x-=s[c[t][0]]+1,t=c[t][1];    }    return t;}int build(int L,int R){    if(L>R) return 0;    int m=(L+R)>>1;    update(m,build(L,m-1),0);    update(m,build(m+1,R),1);    return m;}int main(){    while(scanf("%d%d",&n,&m),n>=0&&m>=0)    {        memset(sign,0,sizeof(sign));        memset(s,0,sizeof(s));        memset(p,0,sizeof(p));        memset(c,0,sizeof(c));        root=build(1,n+2);        int A,B,C,i,r1,r2;        char op[10];        while(m--)        {            scanf("%s",op);            if(op[0]=='C')            {                scanf("%d%d%d",&A,&B,&C);                r1=select(A);                r2=select(B+2);                splay(r1,root);                splay(r2,c[root][1]);                i=c[c[root][1]][0];                c[c[root][1]][0]=0;                update(c[root][1],0,0);                update(root,c[root][1],1);                r1=select(C+1);                r2=select(C+2);                splay(r1,root);                splay(r2,c[root][1]);                c[c[root][1]][0]=i;                update(c[root][1],i,0);                update(root,c[root][1],1);            }            else            {                scanf("%d%d",&A,&B);                r1=select(A);                r2=select(B+2);                splay(r1,root);                splay(r2,c[r1][1]);                i=c[root][1];                i=c[i][0];                sign[i]^=1;            }        }        for(i=2;i

  

转载地址:http://zryva.baihongyu.com/

你可能感兴趣的文章
基于RBAC权限管理
查看>>
基于Internet的软件工程策略
查看>>
数学公式的英语读法
查看>>
留德十年
查看>>
迷人的卡耐基说话术
查看>>
PHP导出table为xls出现乱码解决方法
查看>>
PHP问题 —— 丢失SESSION
查看>>
Java中Object类的equals()和hashCode()方法深入解析
查看>>
数据库
查看>>
Vue------第二天(计算属性、侦听器、绑定Class、绑定Style)
查看>>
dojo.mixin(混合进)、dojo.extend、dojo.declare
查看>>
Python 数据类型
查看>>
iOS--环信集成并修改头像和昵称(需要自己的服务器)
查看>>
PHP版微信权限验证配置,音频文件下载,FFmpeg转码,上传OSS和删除转存服务器本地文件...
查看>>
教程前言 - 回归宣言
查看>>
PHP 7.1是否支持操作符重载?
查看>>
Vue.js 中v-for和v-if一起使用,来判断select中的option为选中项
查看>>
Java中AES加密解密以及签名校验
查看>>
定义内部类 继承 AsyncTask 来实现异步网络请求
查看>>
VC中怎么读取.txt文件
查看>>