• HDU


    题意:有n个数排成环,m个操作1.当前位置后k2个加一个数,2当前位置后k1个翻转,3当前位置后面插入一个数,4删除当前位置的数,5将当前位置前移或后移6查询当前位置的权值
    题解:splay裸题,唯一麻烦的是翻转操作,因为可能不连续,单独考虑即可

    //#pragma GCC optimize(2)
    //#pragma GCC optimize(3)
    //#pragma GCC optimize(4)
    //#pragma GCC optimize("unroll-loops")
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define db double
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define ld long double
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pll pair<ll,ll>
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    //#define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define fin freopen("a.txt","r",stdin)
    #define fout freopen("c.txt","w",stdout)
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    template<typename T>
    inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
    template<typename T>
    inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
    inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
    inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
    inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;}
    
    using namespace std;
    
    const double eps=1e-8;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int N=500000+10,maxn=200000+10,inf=0x3f3f3f3f;
    
    int n;
    struct Splay{
        struct Node{
            Node* ch[2];
            int v,s;
            int flip,lazy;
            int cmp(int x)const{
                int d = x - ch[0]->s;
                if(d==1)return -1;
                return d<=0 ? 0:1;
            }
            void maintain()
            {
                s = 1 + ch[0]->s + ch[1]->s;
            }
            void pushdown()
            {
                if(flip)
                {
                    flip=0;
                    swap(ch[0],ch[1]);
                    ch[0]->flip = !(ch[0]->flip);
                    ch[1]->flip = !(ch[1]->flip);
                }
                if(lazy!=0)
                {
                    if(ch[0]->s!=0)ch[0]->v+=lazy;
                    if(ch[1]->s!=0)ch[1]->v+=lazy;
                    ch[0]->lazy+=lazy;
                    ch[1]->lazy+=lazy;
                    lazy=0;
                }
            }
        };
        Node pp[N];
        int cnt;
        Node* null;
        void Rotate(Node* &o,int d)
        {
            Node* k = o->ch[d^1];
            o->ch[d^1] = k->ch[d];
            k->ch[d] = o;
            o->maintain();k->maintain();
            o = k;
        }
        void splay(Node* &o,int k)
        {
            o->pushdown();
            int d = o->cmp(k);
            if(d==1)k -= o->ch[0]->s + 1;
            if(d!=-1)
            {
                Node* p = o->ch[d];
                p->pushdown();
                int d2 = p->cmp(k);
                int k2 = (d2==0 ? k:k-p->ch[0]->s-1);
                if(d2!=-1)
                {
                    splay(p->ch[d2],k2);
                    if(d==d2)Rotate(o,d^1);
                    else Rotate(o->ch[d],d);
                }
                Rotate(o,d^1);
            }
        }
        Node* Merge(Node* left,Node* right)
        {
            splay(left,left->s);
            left->ch[1] = right;
            left->maintain();
            return left;
        }
        void split(Node* o,int k,Node* &left,Node* &right)
        {
            splay(o,k);
            right = o->ch[1];
            o->ch[1] = null;
            left = o;
            left->maintain();
        }
        Node *root,*left,*right;
        void init(int sz)
        {
            cnt=0;
            null=&pp[++cnt];
            null->s=0;
            root=&pp[++cnt];
            scanf("%d",&root->v);
            root->flip=root->lazy=0;root->s=1;
            root->ch[0]=root->ch[1]=null;
            root->maintain();
            Node* p;
            for(int i=2;i<=sz;i++)
            {
                p=&pp[++cnt];
                scanf("%d",&p->v);
                p->s=p->flip=0;
                p->lazy=0;
                p->ch[0]=root,p->ch[1]=null;
                root=p;
                root->maintain();
            }
        }
        void ins(int pos,int x)
        {
            Node *mid;mid=&pp[++cnt];
            mid->v=x;
            mid->flip=0,mid->lazy=0;
            mid->ch[0]=mid->ch[1]=null;
            mid->maintain();
            if(pos==root->s)root=Merge(root,mid);
            else
            {
                split(root,pos,left,right);
                root=Merge(left,Merge(mid,right));
    //            print(root);
            }
        }
        void del(int pos)
        {
            if(pos==1)
            {
                split(root,1,left,right);
                root=right;
            }
            else if(pos==n)
            {
                split(root,pos-1,left,right);
                root=left;
            }
            else
            {
                split(root,pos,left,right);
                Node *mid;
                split(left,pos-1,left,mid);
                root=Merge(left,right);
            }
        }
        int change(int l,int r,int x,int op)//1-add,2-rev,3-query
        {
            int ans=0;
            if(l==1&&r==root->s)
            {
                if(op==1)
                {
                    root->lazy+=x;
                    root->v+=x;
                }
                else if(op==2)root->flip^=1;
                else ans=root->v;
            }
            else if(l==1&&r!=root->s)
            {
                split(root,r,left,right);
                if(op==1)
                {
                    left->lazy+=x;
                    left->v+=x;
                }
                else if(op==2)left->flip^=1;
                else ans=left->v;
                root=Merge(left,right);
            }
            else if(l!=1&&r==root->s)
            {
                split(root,l-1,left,right);
                if(op==1)
                {
                    right->lazy+=x;
                    right->v+=x;
                }
                else if(op==2)right->flip^=1;
                else ans=right->v;
                root=Merge(left,right);
            }
            else
            {
                split(root,r,left,right);
                Node *mid;
                split(left,l-1,left,mid);
                if(op==1)
                {
                    mid->lazy+=x;
                    mid->v+=x;
                }
                else if(op==2)mid->flip^=1;
                else ans=mid->v;
                root=Merge(left,Merge(mid,right));
            }
            return ans;
        }
        void rev(int l1,int r1,int l2,int r2)
        {
    //        printf("%d %d %d %d
    ",l1,r1,l2,r2);
            if(r1-l1==r2-l2)
            {
                split(root,l2-1,left,right);
                Node *mid;
                split(left,r1,left,mid);
                left->flip^=1,right->flip^=1;
                root=Merge(right,Merge(mid,left));
            }
            else if(r1-l1>r2-l2)
            {
                int len=r2-l2+1,te=r1-len+1;
    //            printf("%d %d
    ",len,te);
                Node *mid1;Node *mid2;
                split(root,l2-1,left,right);
                split(left,r1,left,mid2);
                split(left,te-1,left,mid1);
                mid1->flip^=1;
                left->flip^=1;right->flip^=1;
                root=Merge(Merge(left,right),Merge(mid2,mid1));
            }
            else
            {
                int len=r1-l1+1,te=l2+len-1;
                Node *mid1;Node *mid2;
                split(root,te,left,right);
                split(left,l2-1,left,mid2);
                split(left,r1,left,mid1);
                mid2->flip^=1;
                left->flip^=1;right->flip^=1;
                root=Merge(Merge(mid2,mid1),Merge(left,right));
            }
        }
        void print(Node *o)
        {
            o->pushdown();
            printf("%d %d %d++
    ",o->ch[0]->v,o->v,o->ch[1]->v);
            if(o->ch[0]!=null)print(o->ch[0]);
            if(o->ch[1]!=null)print(o->ch[1]);
        }
    }sp;
    char op[10];
    int main()
    {
        int cas=0,m,k1,k2;
        while(~scanf("%d%d%d%d",&n,&m,&k1,&k2))
        {
            if(!n&&!m&&!k1&&!k2)break;
            int now=1;
            sp.init(n);
            printf("Case #%d:
    ",++cas);
            while(m--)
            {
                scanf("%s",op);
                if(op[0]=='a')
                {
                    int x;scanf("%d",&x);
                    if(now+k2-1>n)
                    {
                        sp.change(now,n,x,1);
                        sp.change(1,now+k2-n-1,x,1);
                    }
                    else sp.change(now,now+k2-1,x,1);
                }
                else if(op[0]=='r')
                {
                    if(now+k1-1>n)sp.rev(1,now+k1-n-1,now,n);
                    else sp.change(now,now+k1-1,0,2);
                }
                else if(op[0]=='i')
                {
                    int x;scanf("%d",&x);
                    sp.ins(now,x);n++;
                }
                else if(op[0]=='d')
                {
                    sp.del(now);
                    if(now==n)now=1;
                    n--;
                }
                else if(op[0]=='m')
                {
                    int x;scanf("%d",&x);
                    if(x==1)
                    {
                        now--;
                        if(now<=0)now=n;
                    }
                    else
                    {
                        now++;
                        if(now>n)now=1;
                    }
                }
                else printf("%d
    ",sp.change(now,now,0,3));
            }
        }
        return 0;
    }
    /********************
    5 100 3 4
    1 2 3 4 5
    move 1
    reverse
    query
    ********************/
    
  • 相关阅读:
    小实例 hangman game
    二分搜索
    基于xml的aop开发
    Discuz! 6.x/7.x 全局变量防御绕过导致命令执行
    PHP执行linux系统命令
    IP反查网站,ip反查接口,旁站查询接口大全,通过IP查域名汇总:
    取消sudo的密码
    linux之kali系统ssh服务开启
    Linux下自动备份MySQL数据库详细操作步骤(转载)
    MongoDB学习笔记(一) MongoDB介绍及安装
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/9799973.html
Copyright © 2020-2023  润新知