zoukankan      html  css  js  c++  java
  • D4 HL 数据结构

    今天都不会;

    太神仙了 我回来再补吧

    丢一个树剖+线段树表示我没白坐一天;

    https://www.luogu.org/problemnew/show/P2486

    //#include<bits/stdc++.h>
    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<ctime>
    #include<algorithm>
    #include<queue>
    #include<deque>
    #include<vector>
    #include<map>
    #include<stack>
    #include<set>
    #include<bitset>
    #include<cstdlib>
    using namespace std;
    #define N 100010 
    template<typename T>inline void read(T &x)
    {
        x=0;
        register int f=1;
        register char ch=getchar();
        while (!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();}
        while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
        x*=f;
    }
    
    int n,m,tot,sz;
    int v[N],vis[N],pl[N],lin[N],belong[N],son[N],d[N],f[N][18];
    
    struct gg {
        int x,y,next;
    }a[N<<1];
    
    struct pink {
        int l,r,lc,rc,s,tag;
    }t[4*N];
    
    inline void add(int x,int y) {
        a[++tot].x=x;
        a[tot].y=y;
        a[tot].next=lin[x];
        lin[x]=tot;
    }
    
    inline void dfs1(int x) {
        vis[x]=son[x]=1;
        for(int i=1;i<=17;i++) {
            if(d[x]<(1<<i))break;
            f[x][i]=f[f[x][i-1]][i-1];
        }
        for(int i=lin[x];i;i=a[i].next) {
            int y=a[i].y;
            if(vis[y])continue;
            d[y]=d[x]+1;
            f[y][0]=x;
            dfs1(y);
            son[x]+=son[y];
        }    
    }
    
    inline void dfs2(int x,int chain) {//当前节点 该链顶端 
        pl[x]=++sz; belong[x]=chain;//pl保存当前dfs序中对应节点编号;belong当前节点记录所熟链的顶端节点; 
        int k=0;
        for(int i=lin[x];i;i=a[i].next) {
            int y=a[i].y;
            if(f[x][0]!=y&&son[k]<son[y])
                k=y;
        }
        if(!k) return ;
        dfs2(k,chain);
        for(int i=lin[x];i;i=a[i].next) {
            int y=a[i].y;
            if(k!=a[i].y&&d[y]>d[x]) {
                dfs2(y,y);//一个点位于轻链底端 那么链顶还是自己; 
            }
        }
    }
    
    inline void build(int p,int l,int r) {
        t[p].l=l; t[p].r=r; 
        t[p].tag=-1; t[p].s=1;
        if(l==r) return ;
        int mid=(l+r)>>1;
        build(p<<1,l,mid); build(p<<1|1,mid+1,r);
    } 
    
    inline void pushup(int k) {
        t[k].lc=t[k<<1].lc;t[k].rc=t[k<<1|1].rc;
        if(t[k<<1].rc^t[k<<1|1].lc) t[k].s=t[k<<1].s+t[k<<1|1].s;
        else t[k].s=t[k<<1].s+t[k<<1|1].s-1;
    }
    
    inline void pushdown(int k) {
        int tmp=t[k].tag;t[k].tag=-1;
        if(tmp==-1||t[k].l==t[k].r)    return;
        t[k<<1].s=t[k<<1|1].s=1;
        t[k<<1].tag=t[k<<1|1].tag=tmp;
        t[k<<1].lc=t[k<<1].rc=tmp;
        t[k<<1|1].lc=t[k<<1|1].rc=tmp;
    }
    
    inline int lca(int x,int y) {
        if(d[x]>d[y]) swap(x,y);
        for(int i=17;i>=0;--i) {
            if(d[f[y][i]]>=d[x]) 
                y=f[y][i];
        }
        if(x==y) return x;
        for(int i=17;i>=0;i--) {
            if(f[y][i]!=f[x][i]) {
                y=f[y][i]; x=f[x][i];
            }
        }
        return f[x][0];
    }
    
    inline void change(int k,int x,int y,int c) {
        pushdown(k);
        int l=t[k].l,r=t[k].r;
        if(l==x&&r==y)
        {    
            t[k].lc=t[k].rc=c;
            t[k].s=1;t[k].tag=c;
            return;
        }
        int mid=(l+r)>>1;
        if(mid>=y) change(k<<1,x,y,c);
        else if(mid<x) change(k<<1|1,x,y,c);
        else {
            change(k<<1,x,mid,c);
            change(k<<1|1,mid+1,y,c);
        }
        pushup(k);
    }
    
    int ask(int k,int x,int y) {
        pushdown(k);
        int l=t[k].l,r=t[k].r;
        if(l==x&&r==y)return t[k].s;
        int mid=(l+r)>>1;
        if(mid>=y)return ask(k<<1,x,y);
        else if(mid<x)return ask(k<<1|1,x,y);
        else {
            int tmp=1;
            if(t[k<<1].rc^t[k<<1|1].lc)tmp=0;
            return ask(k<<1,x,mid)+ask(k<<1|1,mid+1,y)-tmp;
        }
    }
    
    int getc(int k,int x) {
        pushdown(k);
        int l=t[k].l,r=t[k].r;
        if(l==r)    return t[k].lc;
        int mid=(l+r)>>1;
        if(x<=mid)    return getc(k<<1,x);
        else return getc(k<<1|1,x);
    }
    
    inline int slovesum(int x,int y) {
        int sum=0;
        while(belong[x]!=belong[y]) {
            sum+=ask(1,pl[belong[x]],pl[x]);
            if(getc(1,pl[belong[x]])==getc(1,pl[f[belong[x]][0]])) sum--;
            x=f[belong[x]][0];
        }
        sum+=ask(1,pl[y],pl[x]);
        return sum;
    }
    
    inline void slovechange(int x,int y,int c) {
        while(belong[x]!=belong[y]) {
            change(1,pl[belong[x]],pl[x],c);
            x=f[belong[x]][0];
        }
        change(1,pl[y],pl[x],c);
    }
    
    inline void init() {
        read(n); read(m);
        for(int i=1;i<=n;i++) {
            read(v[i]);
        }
        for(int i=1,x,y;i<n;i++) {
            read(x); read(y);
            add(x,y); add(y,x);
        }
    }
    
    inline void slove() {
        int a,b,c;
        d[1]=1;
        dfs1(1);
        dfs2(1,1);
        build(1,1,n);
        for(int i=1;i<=n;i++) {
            change(1,pl[i],pl[i],v[i]);
        }
        for(int i=1;i<=m;i++) {
            char ch[2];
            scanf("%s",ch);
            if(ch[0]=='Q') {
                read(a); read(b);
                int t=lca(a,b);
                printf("%d
    ",slovesum(a,t)+slovesum(b,t)-1);
            }
            else {
                read(a); read(b); read(c);
                int t=lca(a,b);
                slovechange(a,t,c); slovechange(b,t,c); 
            }
        }
    }
    
    int main() {
    //    freopen("a.in","r",stdin);
    //    freopen("a.out","w",stdout);
        init();
        slove();
        return 0;
    }
    View Code
  • 相关阅读:
    D. Constructing the Array
    B. Navigation System
    B. Dreamoon Likes Sequences
    A. Linova and Kingdom
    G. Special Permutation
    B. Xenia and Colorful Gems
    Firetrucks Are Red
    java getInstance()的使用
    java 静态代理和动态代理
    java 类加载机制和反射机制
  • 原文地址:https://www.cnblogs.com/Tyouchie/p/11161536.html
Copyright © 2011-2022 走看看