zoukankan      html  css  js  c++  java
  • 2019西北工业大学程序设计创新实践基地春季选拔赛 I Chino with Rewrite (并查集+树链剖分+线段树)

    链接:https://ac.nowcoder.com/acm/contest/553/I

    思路:离线整棵树,用并查集维护下联通的情况,因为值只有60个,用2的x(1<=x<=60)次方表示,树链剖分线段树区间取或维护,取得的值只要数二进制里面有多少个1就代表有多少个相同的数。

    实现代码;

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define mid ll m = (l + r) >> 1
    const int M = 3e5+10;
    ll sum[M<<2],f[M],head[M],son[M],siz[M],fa[M],dep[M];
    ll cnt,cnt1,n,tid[M],top[M],a[M],op[M],u[M],v[M],ans[M];
    struct node{
        ll to,next;
    }e[M];
    ll Find(ll x){
       if(x == f[x]) return x;
       return f[x] = Find(f[x]);
    }
    
    void add(ll u,ll v){
        e[++cnt1].to=v;e[cnt1].next=head[u];head[u]=cnt1;
        e[++cnt1].to=u;e[cnt1].next=head[v];head[v]=cnt1;
    }
    void dfs1(ll u,ll faz,ll deep){
        dep[u] = deep;
        siz[u] = 1;
        fa[u] = faz;
        //cout<<u<<" "<<faz<<" "<<deep<<endl;
        for(ll i = head[u];i ;i=e[i].next){
            ll v = e[i].to;
            if(v != fa[u]){
                dfs1(v,u,deep+1);
                siz[u] += siz[v];
                if(son[u]==-1||siz[v]>siz[son[u]])
                    son[u] = v;
            }
        }
    }
    
    void dfs2(ll u,ll t){
        top[u] = t;
        tid[u] = cnt;
        //cout<<1<<endl;
        cnt++;
        if(son[u] == -1) return ;
        dfs2(son[u],t);
        for(ll i = head[u];i;i=e[i].next){
            ll v = e[i].to;
            if(v != son[u]&&v != fa[u])
                dfs2(v,v);
        }
    }
    
    void update(ll p,ll c,ll l,ll r,ll rt){
        if(l == r){
            sum[rt] = c;
            return ;
        }
        mid;
        if(p <= m) update(p,c,lson);
        else update(p,c,rson);
        sum[rt] = sum[rt<<1] | sum[rt<<1|1];
    }
    
    ll query(ll L,ll R,ll l,ll r,ll rt){
        if(L <= l&&R >= r){
             return sum[rt];
        }
        mid;
        ll ret = 0;
        if(L <= m) ret |= query(L,R,lson);
        if(R > m) ret |= query(L,R,rson);
        return ret;
    }
    
    ll solve(ll x){
        ll ans = 0;
        while(x){
            ans++;
            x -= (x&-x);
        }
        return ans;
    }
    
    ll ask(ll x,ll y){
        ll ans = 0;
        ll fx = top[x],fy = top[y];
        while(fx != fy){
            if(dep[fx] < dep[fy]) swap(x,y),swap(fx,fy);
            ans |= query(tid[fx],tid[x],1,n,1);
            x = fa[fx]; fx = top[x];
        }
        if(dep[x] > dep[y]) swap(x,y);
        ans |= query(tid[x],tid[y],1,n,1);
        return ans;
    }
    
    int main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0); cout.tie(0);
        ll q; cnt = 1;
        cin>>n>>q;
        memset(son,-1,sizeof(son));
        for(ll i = 1;i <= n;i ++){
            cin>>a[i];f[i] = i;
        }
        for(ll i = 1;i <= q;i ++){
            cin>>op[i]>>u[i]>>v[i];
            if(op[i] == 1){
                ll fx = Find(u[i]),fy = Find(v[i]);
                if(fx != fy) f[fx] = fy,add(u[i],v[i]),ans[i]=1;
            }
            else{
                ll fx = Find(u[i]),fy = Find(v[i]);
                if(fx != fy) ans[i] = -1;
            }
        }
        dfs1(1,0,1); dfs2(1,0);
        for(ll i = 1;i <= q;i ++){
            if(op[i] == 1&&ans[i]==1){
                ll num = (a[u[i]] + a[v[i]])/2;
                a[u[i]] = a[v[i]] = num;
                update(tid[u[i]],1LL<<num,1,n,1);
                update(tid[v[i]],1LL<<num,1,n,1);
    
            }
            else if(op[i] == 2&&ans[i]!=-1){
                ans[i] = solve(ask(u[i],v[i]));
            }
        }
        for(ll i = 1;i <= q;i ++)
            if(op[i] == 2) cout<<ans[i]<<endl;
    
    }
  • 相关阅读:
    【原创】MessageBox设置默认按钮
    探秘Win7计算器,这货不只是计算器
    android fill_parent和match_parent 的区别
    陈晓旭出家申明
    vi语法高亮
    EXTJS 常用控件的使用
    android平台下使用点九PNG技术
    【Android】附加Android源代码Androidandroid_gingerbread_javasrc
    ComboBox控件隐藏fieldLabel不能隐藏问题解决
    ScriptLoader.loadScripts cannot be called while the ScriptLoader is already loading scripts
  • 原文地址:https://www.cnblogs.com/kls123/p/10672641.html
Copyright © 2011-2022 走看看