zoukankan      html  css  js  c++  java
  • P4592 [TJOI2018]异或

    吐槽

    睡起来写道模板清醒一下
    貌似有两个log的树剖写法,还有一个log的Trie树的差分做法(类似于count on a tree),然后一个log的要把两个询问分开写,一个dfs序一个差分,然后我就写了好写的树剖写法
    以及为啥出题人这么喜欢把序列问题放到树上啊。。。
    可持久化Tried树模板难度,懒得写思路

    代码

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int MAXN = 100100;
    struct Node{
        int son[2],sz;
    }Trie[MAXN*40];
    const int MAXlen=30;
    int u[MAXN<<1],v[MAXN<<1],w[MAXN],nxt[MAXN<<1],root[MAXN],dep[MAXN],fir[MAXN],id[MAXN],top[MAXN],sz[MAXN],heason[MAXN],fa[MAXN],cnt,dfs_clock,w_p[MAXN],n,m,Nodecnt;
    void addedge(int ui,int vi){
        ++cnt;
        u[cnt]=ui;
        v[cnt]=vi;
        nxt[cnt]=fir[ui];
        fir[ui]=cnt;
    }
    void dfs1(int u,int f){
        sz[u]=1;
        fa[u]=f;
        dep[u]=dep[f]+1;
        for(int i=fir[u];i;i=nxt[i]){
            if(v[i]==f)
                continue;
            dfs1(v[i],u);
            sz[u]+=sz[v[i]];
            if(heason[u]==0||sz[heason[u]]<sz[v[i]])
                heason[u]=v[i];
        }
    }
    void dfs2(int u,int topf){
        id[u]=++dfs_clock;
        w[id[u]]=w_p[u];
        top[u]=topf;
        if(!heason[u])
            return;
        dfs2(heason[u],topf);
        for(int i=fir[u];i;i=nxt[i]){
            if(v[i]==fa[u]||v[i]==heason[u])
                continue;
            dfs2(v[i],v[i]);
        }
    }
    void insert(int d,int val,int &o){
        Trie[++Nodecnt]=Trie[o];
        o=Nodecnt;
        Trie[o].sz++;
        if(d>=0)
            insert(d-1,val,Trie[o].son[(val>>d)&1]);
    }
    int query(int lroot,int rroot,int val,int d){
        if(d<0)
            return 0;
        int flag=(val>>d)&1;
        if(Trie[rroot].son[!flag]>Trie[lroot].son[!flag])
            return (1<<d)+query(Trie[lroot].son[!flag],Trie[rroot].son[!flag],val,d-1);
        else
            return query(Trie[lroot].son[flag],Trie[rroot].son[flag],val,d-1);
    }
    void build(void){
        for(int i=1;i<=dfs_clock;i++){
            root[i]=root[i-1];
            insert(MAXlen,w[i],root[i]);
        }
    }
    int query(int x,int y,int c){
        int ans=0;
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]])
                swap(x,y);
            ans=max(ans,query(root[id[top[x]]-1],root[id[x]],c,MAXlen));
            x=fa[top[x]];
        }
        if(dep[x]>dep[y])
            swap(x,y);
        ans=max(ans,query(root[id[x]-1],root[id[y]],c,MAXlen));
        return ans;
    }
    int query(int x,int c){
        return query(root[id[x]-1],root[id[x]+sz[x]-1],c,MAXlen);
    }
    int main(){
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&w_p[i]);
        for(int i=1;i<n;i++){
            int a,b;
            scanf("%d %d",&a,&b);
            addedge(a,b);
            addedge(b,a);
        }
        dfs1(1,0);
        dfs2(1,1);
        build();
        for(int i=1;i<=m;i++){
            int opt,x,y,z;
            scanf("%d %d %d",&opt,&x,&y);
            if(opt==1){
                printf("%d
    ",query(x,y));
            }
            else{
                scanf("%d",&z);
                printf("%d
    ",query(x,y,z));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    FAT学习笔记(五)——FAQ
    FAT32学习笔记(五)——fat相关工具
    FAT学习笔记(四)——Dir Entry
    FAT学习笔记(三)--FSInfo
    zabbix介绍
    配置pxe 自动化安装centos6.7
    跳转方式用name方法的话,浏览器返回按钮点击返回时会有BUG
    FormData使用方法详解
    vue中的@click.native
    vue从后台获取数据,并导出EXCEL文件
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10502065.html
Copyright © 2011-2022 走看看