zoukankan      html  css  js  c++  java
  • LOJ #2107. 「JLOI2015」城池攻占 Splay+启发式合并

    这道题拿左偏树做的话时间复杂度好像是 $O(n log n)$ 的,拿 $Splay$ 的话就是 $O(n log^2 n)$ 的.   

    $Splay$ 真恶心,真心不好写,要不是可以练习代码能力的话我才不用 $Splay$.  

    code:   

    #include <bits/stdc++.h>       
    #define ll long long       
    #define N 300006 
    #define setIO(s) freopen(s".in","r",stdin) ,freopen(s".out","w",stdout)  
    using namespace std;  
    const ll inf=7e18+2;   
    ll h[N];
    struct opt 
    {
        int a;  
        ll v;     
    }tree[N];       
    int DE;       
    int n,m,edges,tot,FL,Ans1[N],Ans2[N],ge[N];         
    int dep[N],hd[N],to[N],nex[N],rt[N],ou[N];            
    namespace BST
    {  
        #define lson s[x].ch[0] 
        #define rson s[x].ch[1]  
        struct node 
        {   
            ll v,a,b;  
            int si,ch[2],f,id;  
            void ini() 
            {
                v=0,a=1,b=0;    
                si=1,ch[0]=ch[1]=f=id=0;  
            }   
        }s[N*20];    
        int tot;  
        stack<int>S;       
        inline int get(int x) { return s[s[x].f].ch[1]==x; }   
        inline int newnode()  
        {
            if(S.empty()) 
                return ++tot;   
            else
            {
                int u=S.top(); 
                S.pop();  
                return u;   
            }
        }    
        inline void pushup(int x) 
        {
            s[x].si=s[lson].si+s[rson].si+1;  
        }
        inline void mark_a(int x,ll a) 
        {
            s[x].a*=a,s[x].b*=a;     
            if(s[x].v!=inf&&s[x].v!=-inf)   
                s[x].v*=a;        
        }
        inline void mark_b(int x,ll b) 
        {
            s[x].b+=b;   
            if(s[x].v!=inf&&s[x].v!=-inf)   
                s[x].v+=b;   
        }
        inline void pushdown(int x) 
        {
            if(s[x].a!=1) 
            {
                if(lson)  
                    mark_a(lson,s[x].a);  
                if(rson) 
                    mark_a(rson,s[x].a);  
                s[x].a=1; 
            }
            if(s[x].b) 
            {
                if(lson) 
                    mark_b(lson,s[x].b);  
                if(rson) 
                    mark_b(rson,s[x].b);   
                s[x].b=0;  
            }
        }
        int ins(int &x,int ff,int id,ll v) 
        {
            if(!x) 
            {
                x=newnode();       
                s[x].ini();  
                s[x].f=ff,s[x].id=id,s[x].v=v; 
                return x;      
            }      
            ++s[x].si;  
            pushdown(x);     
            return ins(s[x].ch[v>s[x].v],x,id,v); 
        }  
        inline int find(int x,ll v) 
        {
            int r=0;    
            while(1) 
            {    
                if(!x) 
                    break;  
                pushdown(x);       
                if(s[x].v>=v)  
                    r=x,x=lson;    
                else 
                    x=rson;  
            }
            return r;   
        }   
        inline void rotate(int x) 
        {
            int old=s[x].f,fold=s[old].f,which=get(x);  
            s[old].ch[which]=s[x].ch[which^1];  
            if(s[old].ch[which]) 
                s[s[old].ch[which]].f=old;  
            s[x].ch[which^1]=old,s[old].f=x,s[x].f=fold;  
            if(fold)  
                s[fold].ch[s[fold].ch[1]==old]=x;   
            pushup(old),pushup(x); 
        }
        void splay(int x,int &tar) 
        {
            int u=s[tar].f;  
            for(int fa;(fa=s[x].f)!=u;rotate(x))     
                if(s[fa].f!=u)  
                    rotate(get(fa)==get(x)?fa:x);  
            tar=x;  
        }    
        void ope(int &x,int y) 
        {      
            if(s[y].v!=-inf&&s[y].v!=inf)   
            { 
                int p=ins(x,0,s[y].id,s[y].v);    
                if((rand()%3)==0)   
                    splay(p,x);                          
            }
            pushdown(y);   
            if(s[y].ch[0])  
                ope(x,s[y].ch[0]);   
            if(s[y].ch[1]) 
                ope(x,s[y].ch[1]);   
            S.push(y);     
        }        
        void del(int x) 
        {    
            if(!x)  
                return;   
            if(s[x].v!=inf&&s[x].v!=-inf) 
            {   
                Ans1[FL]+=1;     
                ou[s[x].id]=1;   
                Ans2[s[x].id]+=dep[ge[s[x].id]]-dep[FL];       
            }    
            pushdown(x);   
            if(lson)   
                del(lson);  
            if(rson)  
                del(rson);   
            S.push(x);   
        }  
        #undef lson 
        #undef rson  
    };                
    void add(int u,int v) 
    {
        nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;   
    }      
    void merge(int x,int y) 
    {  
        if(BST::s[rt[x]].si<BST::s[rt[y]].si)       
            swap(rt[x],rt[y]);  
        BST::ope(rt[x],rt[y]);   
    }               
    void dfs(int x,int ff) 
    {
        dep[x]=dep[ff]+1;           
        BST::ins(rt[x],0,0,inf);  
        BST::ins(rt[x],0,0,-inf);     
        for(int i=hd[x];i;i=nex[i]) 
        {
            int y=to[i];      
            dfs(y,x),merge(x,y);  
        }       
        FL=x;    
        int q=BST::find(rt[x],h[x]);                                 
        BST::splay(q,rt[x]);             
        BST::s[BST::s[q].ch[0]].f=0; 
        BST::del(BST::s[q].ch[0]);   
        BST::s[q].ch[0]=0;                           
        BST::pushup(q);                                             
        if(x!=1)                
        {
            if(tree[x].a==0)   
                BST::mark_b(q,tree[x].v);   
            if(tree[x].a==1)  
                BST::mark_a(q,tree[x].v);         
        }                     
    }
    int main() 
    { 
        // setIO("input");     
        int i,j;    
        scanf("%d%d",&n,&m);         
        for(i=1;i<=n;++i)          
            scanf("%lld",&h[i]);         
        for(i=2;i<=n;++i)      
            scanf("%d%d%lld",&j,&tree[i].a,&tree[i].v),add(j,i);            
        for(i=1;i<=m;++i) 
        {
            ll v; 
            int u;        
            scanf("%lld%d",&v,&u);     
            ge[i]=u;  
            BST::ins(rt[u],0,i,v);        
        }     
        dfs(1,0);       
        for(i=1;i<=n;++i)   
            printf("%d
    ",Ans1[i]);  
        for(i=1;i<=m;++i)  
            if(!ou[i])      
                printf("%d
    ",dep[ge[i]]);  
            else 
                printf("%d
    ",Ans2[i]);  
        return 0;
    }
    

      

  • 相关阅读:
    openldap---ldapsearch使用
    自旋锁与相互排斥锁之抉择
    探索Android中的Parcel机制(上)
    我的Android开发相关文章
    SoftReference
    Windows7WithSP1/TeamFoundationServer2012update4/SQLServer2012
    机器学习中规则化和模型选择知识
    Java中System的详细用法
    Java中System的详细用法
    Java中System的详细用法
  • 原文地址:https://www.cnblogs.com/guangheli/p/12483076.html
Copyright © 2011-2022 走看看