• BZOJ5338 [TJOI2018] Xor 【可持久化Trie树】【dfs序】


    题目分析:

      很无聊的一道题目。首先区间内单点对应异或值的询问容易想到trie树。由于题目在树上进行,case1将路径分成两段,然后dfs的时候顺便可持久化trie树做询问。case2维护dfs序,对dfs序建可持久化的trie树。这样做的空间复杂度是O(nw),时间复杂度是O(nw).

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 const int maxn=102000;
      5 
      6 int n,q;
      7 int v[maxn];
      8 vector<int> g[maxn];
      9 
     10 vector<pair<int,int> > qy[maxn];
     11 vector<pair<int,int> > vec;
     12 
     13 int ans[maxn],num,kd[maxn];
     14 int dep[maxn],dfsin[maxn],dfsout[maxn],fa[maxn];
     15 
     16 vector<pair<int,int> > Lca[maxn];
     17 int pre[maxn];
     18 
     19 int found(int x){
     20     int rx = x; while(pre[rx] != rx) rx = pre[rx];
     21     while(pre[x] != rx){
     22     int t = pre[x]; pre[x] = rx; x = t;
     23     }
     24     return rx;
     25 }
     26 
     27 void dfs(int now,int dp,int f){
     28     dfsin[now] = dfsout[now] = ++num;fa[now] = f; dep[now] = dp;
     29     for(auto pr:Lca[now]){
     30     if(dep[pr.first] == 0) continue;
     31     int la = found(pr.first);
     32     qy[now].push_back(make_pair(la,pr.second));
     33     qy[pr.first].push_back(make_pair(la,pr.second));
     34     }
     35     for(auto i:g[now]){
     36     if(i == f) continue;
     37     dfs(i,dp+1,now);
     38     dfsout[now] = dfsout[i];
     39     }
     40     pre[found(now)] = found(f);
     41 }
     42 
     43 void read(){
     44     scanf("%d%d",&n,&q);
     45     for(int i=1;i<=n;i++) scanf("%d",&v[i]);
     46     for(int i=1;i<n;i++){
     47     int x,y; scanf("%d%d",&x,&y);
     48     g[x].push_back(y); g[y].push_back(x);
     49     }
     50     for(int i=1;i<=q;i++){
     51     int cas; scanf("%d",&cas);
     52     if(cas == 1){
     53         int x,y; scanf("%d%d",&x,&y);
     54         vec.push_back(make_pair(x,i));kd[i] = y;
     55     }else{
     56         int x,y,z; scanf("%d%d%d",&x,&y,&z);
     57         Lca[x].push_back(make_pair(y,i));
     58         if(x!=y) Lca[y].push_back(make_pair(x,i));
     59         kd[i] = z;
     60     }
     61     }
     62     for(int i=1;i<=n;i++) pre[i] = i;
     63     dfs(1,1,0);
     64 }
     65 
     66 int his[maxn],om;
     67 int sz[maxn*130],ch[maxn*130][2];
     68 
     69 void follow(int pt,int last,int dt){
     70     int hbit = 30;
     71     while(hbit!=-1){
     72     if((1<<hbit)&dt){
     73         ch[pt][0] = ch[last][0];
     74         ch[pt][1] = ++num;
     75         pt = num; last = ch[last][1];
     76         sz[pt] = sz[last]+1;
     77     }else{
     78         ch[pt][1] = ch[last][1];
     79         ch[pt][0] = ++num;
     80         pt = num; last = ch[last][0];
     81         sz[pt] = sz[last]+1;
     82     }
     83     hbit--;
     84     }
     85 }
     86 
     87 void ins(int now){
     88     int last = his[om-1];
     89     num++;int pt = num; sz[pt] = sz[last]+1;
     90     his[om] = num;
     91     follow(pt,last,v[now]);
     92 }
     93 
     94 int query(int now,int last,int z){
     95     now = his[now]; last = his[last];
     96     int hbit = 30;
     97     while(hbit!=-1){
     98     if((1<<hbit)&z){
     99         if(sz[ch[now][0]]-sz[ch[last][0]]){
    100         now = ch[now][0];last = ch[last][0];
    101         }else{
    102         z -= (1<<hbit);now = ch[now][1];last = ch[last][1];
    103         }
    104     }else{
    105         if(sz[ch[now][1]]-sz[ch[last][1]]){
    106         z += (1<<hbit);
    107         now = ch[now][1];last = ch[last][1];
    108         }else{
    109         now = ch[now][0];last = ch[last][0];
    110         }
    111     }
    112     hbit--;
    113     }
    114     return z;
    115 }
    116 
    117 void del(int now){his[om] = 0;}
    118 
    119 void dfs2(int now){
    120     om++;ins(now);
    121     for(auto pr:qy[now]){
    122     int last = dep[pr.first]-1,data = kd[pr.second];
    123     ans[pr.second] = max(ans[pr.second],query(dep[now],last,data));
    124     }
    125     for(auto i:g[now]){
    126     if(i == fa[now]) continue;
    127     dfs2(i); 
    128     }
    129     del(now);om--;
    130 }
    131 
    132 void dfs3(int now){
    133     om++;ins(now);
    134     for(auto i:g[now]){
    135     if(i == fa[now]) continue;
    136     dfs3(i);
    137     }
    138 }
    139 
    140 void work(){
    141     num = 1;his[0] = 1;
    142     dfs2(1);
    143     memset(ch,0,sizeof(ch));memset(sz,0,sizeof(sz));
    144     num = 1;his[0] = 1;om = 0;
    145     dfs3(1);
    146     for(auto pr:vec){
    147     int st = dfsin[pr.first],ed = dfsout[pr.first];
    148     ans[pr.second] = query(ed,st-1,kd[pr.second]);
    149     }
    150     for(int i=1;i<=q;i++) printf("%d
    ",ans[i]);
    151 }
    152 
    153 int main(){
    154     read();
    155     work();
    156     return 0;
    157 }
  • 相关阅读:
    linux串口驱动分析
    redis 源代码分析(一) 内存管理
    EJB3.0开发环境的搭建
    Google App Engine 学习和实践
    用EnableMenuItem不能使菜单变灰的原因
    hdu 1171 Big Event in HDU(母函数)
    Stack-based buffer overflow in acdb audio driver (CVE-2013-2597)
    遗传算法入门到掌握(一)
    Amazon SQS简单介绍 上篇
    Matlab画图-非常具体,非常全面
  • 原文地址:https://www.cnblogs.com/Menhera/p/9059869.html
Copyright © 2020-2023  润新知