• [NOI2005]维修数列


    ## [ 传送门 ](https://www.lydsy.com/JudgeOnline/problem.php?id=1500)

    Solution

    题意

    维护一个数组,支持区间加点删点,区间覆盖,区间翻转,区间求和,求和最大的子序列

    fhq模板题?
    学完fhq后,就再也不爱打splay了 ......
    注意回收点的时候要删标记,否则神奇MLE


    Code

    #include<bits/stdc++.h>
    #define ll long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return x*f;
    }
    #define MN 500005
    #define inf 550000000 
    int s[MN];
    std::queue<int> q;
    class fhq
    {
        private:
            int sz;
            int pri[MN],ls[MN],rs[MN],siz[MN];
            int pr[MN],su[MN],tt[MN],cover[MN],V[MN],ans[MN];
            /*
    		class QUEUE
    		{
            	private:
    				int q[MN<<3],top;		
    			public:
    				QUEUE(int _top=0):top(_top){}
    				inline void push(int x){q[top]=x;(++top)%=MN;}
    				inline bool empty(){return top==0;}
    				inline int front(){return q[top-1];}
    				inline void pop(){top--;}
    		}q;
    		*/
            bool rev[MN];
            inline unsigned int random()
            {
                static unsigned int x=23333;
                return x^=x<<13,x^=x>>17,x^=x<<5;
            }
            inline void up(int x)
            {
                siz[x]=1+siz[ls[x]]+siz[rs[x]];
                tt[x]=tt[ls[x]]+tt[rs[x]]+V[x];
                if(!ls[x]&&!rs[x]){pr[x]=su[x]=ans[x]=V[x];}
                else if(!ls[x])
                {
                    pr[x]=V[x]+max(0,pr[rs[x]]);
                    su[x]=max(su[rs[x]],tt[rs[x]]+V[x]);
                    ans[x]=max(ans[rs[x]],pr[x]);
                }
                else if(!rs[x])
                {
                    pr[x]=max(pr[ls[x]],tt[ls[x]]+V[x]);
                    su[x]=V[x]+max(0,su[ls[x]]);
                    ans[x]=max(ans[ls[x]],su[x]);
                }
                else
                {
                    pr[x]=max(pr[ls[x]],tt[ls[x]]+V[x]+max(0,pr[rs[x]]));
                	su[x]=max(su[rs[x]],tt[rs[x]]+V[x]+max(0,su[ls[x]]));
                	ans[x]=max(ans[ls[x]],ans[rs[x]]);
                	ans[x]=max(ans[x],max(0,su[ls[x]])+V[x]+max(0,pr[rs[x]]));
                }
    
            }
            inline void update(int x,int opt)
            {
            	if(!x) return; 
            	if(opt==1)
                {
                    std::swap(pr[x],su[x]);std::swap(ls[x],rs[x]);
                    rev[ls[x]]^=1;rev[rs[x]]^=1;
                }
                if(opt==3)
                {
                    V[x]=cover[x];tt[x]=cover[x]*siz[x];
                    su[x]=pr[x]=ans[x]=max(cover[x],cover[x]*siz[x]);
                    cover[ls[x]]=cover[rs[x]]=cover[x];
                    rev[ls[x]]=rev[rs[x]]=0;
                }
            }
            inline void down(int x)
            {
            	if(cover[x]<inf) update(ls[x],3),update(rs[x],3),cover[x]=inf;
                if(rev[x]) update(ls[x],1),update(rs[x],1),rev[x]=0;
            }
            inline void recycle(int p)
    		{
        		if(!p) return;
        		int L=ls[p],R=rs[p];
        		recycle(L);recycle(R);q.push(p);
        		ls[p]=rs[p]=rev[p]=0;
    		}
    	public:
            int rt;
            int Merge(int rt1,int rt2)
            {
            	if(rt1) down(rt1);
            	if(rt2) down(rt2);
                if(!rt1||!rt2) return rt2|rt1;
                if(pri[rt1]<pri[rt2])
                {
            		rs[rt1]=Merge(rs[rt1],rt2);
            		up(rt1);return rt1;
        		}
        		else
                {
            		ls[rt2]=Merge(rt1,ls[rt2]);
            		up(rt2);return rt2;
        		}
            }
            
            void Split(int x,int k,int&rt1,int&rt2)
            {
                if(!x) return (void)(rt1=rt2=0);
                down(x);
                if(k<=siz[ls[x]])
                {
                    Split(ls[x],k,rt1,rt2);
                    ls[x]=rt2;up(x);rt2=x;
                }
                else
                {
                    Split(rs[x],k-siz[ls[x]]-1,rt1,rt2);
                    rs[x]=rt1;up(x);rt1=x;
                }
            }
            void Build(int &x,int l,int r)
            {
                if(l>r) return;int mid=l+r>>1;
                if(!q.empty()) x=q.front(),q.pop();else x=++sz;
                ans[x]=tt[x]=V[x]=s[mid],cover[x]=inf,pri[x]=random();
                if(l==r) return(void)(pr[x]=su[x]=V[x],siz[x]=1);
                Build(ls[x],l,mid-1),Build(rs[x],mid+1,r);up(x);
            }
            void Reverse(int l,int len)
            {
            	register int rt1,rt2,rt3,rt4;
            	Split(rt,l-1,rt1,rt2);Split(rt2,len,rt3,rt4);
            	rev[rt3]^=1;update(rt3,1);rt=Merge(rt1,Merge(rt3,rt4));
            }
            void Replace(int l,int len,int c)
            {
                register int rt1,rt2,rt3,rt4;
            	Split(rt,l-1,rt1,rt2);Split(rt2,len,rt3,rt4);
            	cover[rt3]=c;update(rt3,3);rev[rt3]=0;rt=Merge(rt1,Merge(rt3,rt4));
            }
            void Delete(int l,int len)
            {
            	register int rt1,rt2,rt3,rt4;
            	Split(rt,l-1,rt1,rt2);Split(rt2,len,rt3,rt4);
            	rt=Merge(rt1,rt4);recycle(rt3);
            }
            void Insert(int pos,int r)
            {
                register int rt1,rt2,rt3;
                Split(rt,pos,rt1,rt2);Build(rt3,1,r);
                rt=Merge(rt1,Merge(rt3,rt2));
            }
            void QueSum(int l,int len)
            {
                register int rt1,rt2,rt3,rt4;
                Split(rt,l-1,rt1,rt2);Split(rt2,len,rt3,rt4);
                printf("%d
    ",tt[rt3]);rt=Merge(rt1,Merge(rt3,rt4));
            }
            void QueMax(){printf("%d
    ",ans[rt]);}
    }T;
    int main()
    {
        register int i,n,m,posi,tot,c;
        register char ch[50];n=read();m=read();
        for(i=1;i<=n;++i) s[i]=read();
        T.Build(T.rt,1,n);
        while(m--)
        {
        	scanf("%s",ch+1);
        	if(ch[1]=='I')
        	{
        		posi=read();tot=read();
        		for(i=1;i<=tot;++i) s[i]=read();
        		T.Insert(posi,tot);
            }
            if(ch[1]=='D')
            {
                posi=read(),tot=read();
                T.Delete(posi,tot);
            }
            if(ch[1]=='M'&&ch[3]=='K')
            {
                posi=read();tot=read();c=read();
                T.Replace(posi,tot,c);
            }
            if(ch[1]=='R')
            {
                posi=read();tot=read();
                T.Reverse(posi,tot);
            }
            if(ch[1]=='G')
            {
                posi=read();tot=read();
                T.QueSum(posi,tot);
            }
            if(ch[1]=='M'&&ch[3]=='X'){T.QueMax();}
        }
        return 0;
    }
    


    Blog来自PaperCloud,未经允许,请勿转载,TKS!

  • 相关阅读:
    今日头条、Face++开发岗面经
    美团offer面经
    成都百度测试开发一二面面经
    美团四面面经
    久邦数码(3G门户)面试
    58 面试
    好未来提前批
    百度提前批
    新浪面经
    Java Programs
  • 原文地址:https://www.cnblogs.com/PaperCloud/p/10159151.html
Copyright © 2020-2023  润新知