zoukankan      html  css  js  c++  java
  • LOJ #2831. 「JOISC 2018 Day 1」道路建设 线段树+Link-cut-tree

    用 LCT 维护颜色相同连通块,然后在线段树上查一下逆序对个数就可以了. 

    code:

    #include <cstdio> 
    #include <algorithm> 
    #include <cstring>     
    #include <string>     
    #define N 100005 
    #define ll long long 
    using namespace std;      
    namespace IO 
    { 
        void setIO(string s) 
        {
            string in=s+".in"; 
            string out=s+".out"; 
            freopen(in.c_str(),"r",stdin); 
            // freopen(out.c_str(),"w",stdout);  
        }
    };  
    ll ans;   
    int n,val[N],A[N];     
    namespace seg 
    {     
        int lazy[N<<2],sum[N<<2];      
        void mark(int now) { sum[now]=0,lazy[now]=1; }    
        void pushdown(int now) 
        { 
            if(lazy[now])  
                mark(now<<1),mark(now<<1|1),lazy[now]=0; 
        }       
        void update(int l,int r,int now,int p,int v) 
        {
            if(l==r) { sum[now]+=v;   return; }    
            pushdown(now);  
            int mid=(l+r)>>1;     
            if(p<=mid)  
                update(l,mid,now<<1,p,v);  
            else 
                update(mid+1,r,now<<1|1,p,v);  
            sum[now]=sum[now<<1]+sum[now<<1|1];   
        }
        int query(int l,int r,int now,int L,int R) 
        { 
            if(L>R) 
                return 0;  
            if(l>=L&&r<=R)  
                return sum[now];  
            pushdown(now);         
            int re=0,mid=(l+r)>>1;  
            if(L<=mid)   
                re+=query(l,mid,now<<1,L,R);   
            if(R>mid)  
                re+=query(mid+1,r,now<<1|1,L,R);  
            return re;  
        }
    };  
    namespace LCT 
    { 
        #define lson s[x].ch[0] 
        #define rson s[x].ch[1]  
        struct node { 
            int ch[2],rev,f,tag,size;     
        }s[N];       
        int sta[N];  
        inline int get(int x) { return s[s[x].f].ch[1]==x; }   
        inline int isr(int x) { return s[s[x].f].ch[0]!=x&&s[s[x].f].ch[1]!=x; }      
        inline void pushup(int x)     { s[x].size=s[lson].size+s[rson].size+1; }    
        inline void mark(int x,int v) { s[x].tag=v; }    
        inline void pushdown(int x) 
        {
            if(lson) mark(lson,s[x].tag);  
            if(rson) mark(rson,s[x].tag);            
        }
        inline void rotate(int x) 
        {     
            int old=s[x].f,fold=s[old].f,which=get(x);  
            if(!isr(old))      
                s[fold].ch[s[fold].ch[1]==old]=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;    
            pushup(old),pushup(x);          
        } 
        inline void splay(int x) 
        {     
            int v=0,u=x,fa;  
            for(sta[++v]=u;!isr(u);u=s[u].f) 
                sta[++v]=s[u].f;              
            for(;v;--v) 
                pushdown(sta[v]);   
            for(u=s[u].f;(fa=s[x].f)!=u;rotate(x)) 
                if(s[fa].f!=u) 
                    rotate(get(fa)==get(x)?fa:x);  
        }     
        inline void Access(int x,int v) 
        {  
            for(int y=0;x;y=x,x=s[x].f)  
            { 
                splay(x),rson=0,pushup(x);   
                ans+=(ll)s[x].size*seg::query(1,n,1,1,s[x].tag-1);     
                seg::update(1,n,1,s[x].tag,s[x].size);    
                rson=y,s[x].tag=v,pushup(x);    
            }
        }   
        inline void link(int x,int y) { s[y].f=x; }    
        #undef lson 
        #undef rson                    
    };  
    int main() 
    { 
        // IO::setIO("input");  
        int i,j;           
        scanf("%d",&n);  
        for(i=1;i<=n;++i)  
            scanf("%d",&val[i]),A[i]=val[i]; 
        sort(A+1,A+1+n);  
        for(i=1;i<=n;++i) 
            val[i]=lower_bound(A+1,A+1+n,val[i])-A,LCT::s[i].tag=val[i];    
        for(i=1;i<n;++i) 
        {
            int x,y;    
            scanf("%d%d",&x,&y);      
            ans=0;  
            seg::mark(1);            
            LCT::Access(x,val[y]);     
            LCT::link(x,y);   
            printf("%lld
    ",ans);       
        }
        return 0;
    }               
    

      

  • 相关阅读:
    Leetcode#129 Sum Root to Leaf Numbers
    Leetcode#15 3Sum
    Leetcode#16 3Sum Closest
    Leetcode#127 Word Ladder
    Leetcode#2 Add Two Numbers
    Leetcode#18 4Sum
    vue.js入门(3)——组件通信
    vue.js慢速入门(2)
    vue 基础介绍
    vue.js中v-for的使用及索引获取
  • 原文地址:https://www.cnblogs.com/guangheli/p/12377889.html
Copyright © 2011-2022 走看看