zoukankan      html  css  js  c++  java
  • BZOJ2819 Nim(DFS序)

    题目:单点修改、树链查询。

    可以直接用树链剖分做。。

    修改是O(QlogN),查询是O(QlogNlogN),Q=N=500000;

    听说会超时。。

    这题也可以用DFS序来做。

    先不看修改,单单查询:可以求出每个点到根的xor值,那么对任意两点的查询就等于xor(u)^xor(v)^val(lca(u,v));

    如果有修改:修改仅仅是单个点,而维护的只是点到根的路径,因此修改仅仅会影响到以这个点为根的子树的所有结点到根的信息。

    所以用DFS序把子树们化为连续区间用线段树维护,修改本质上是个线段树的区间修改,查询是个单点查询。

    每次修改和查询都是O(logN)。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 using namespace std;
      5 #define MAXN 550000
      6 struct Edge{
      7     int v,nxt;
      8 }edge[MAXN<<1];
      9 int NE,head[MAXN];
     10 void addEdge(int u,int v){
     11     edge[NE].v=v; edge[NE].nxt=head[u]; head[u]=NE++;
     12 }
     13 int n,stone[MAXN];
     14 int odr,stack[MAXN],l[MAXN],r[MAXN],dep[MAXN],fa[20][MAXN],val[MAXN];
     15 void dfs(){
     16     int top=0;
     17     stack[++top]=1;
     18     val[1]=stone[1];
     19     while(top){
     20         int u=stack[top];
     21         if(l[u]){
     22             r[u]=odr; --top;
     23             continue;
     24         }
     25         l[u]=++odr;
     26         for(int i=head[u]; i!=-1; i=edge[i].nxt){
     27             int v=edge[i].v;
     28             if(fa[0][u]==v) continue;
     29             fa[0][v]=u; dep[v]=dep[u]+1; val[v]=val[u]^stone[v]; stack[++top]=v;
     30         }
     31     }
     32 }
     33 
     34 int tree[MAXN<<2],N,x,y,z;
     35 void update(int i,int j,int k){
     36     if(x<=i && j<=y){
     37         tree[k]^=z;
     38         return;
     39     }
     40     if(tree[k]){
     41         tree[k<<1]^=tree[k]; tree[k<<1|1]^=tree[k];
     42         tree[k]=0;
     43     }
     44     int mid=i+j>>1;
     45     if(x<=mid) update(i,mid,k<<1);
     46     if(y>mid) update(mid+1,j,k<<1|1);
     47 }
     48 int query(int i,int j,int k){
     49     if(i==j) return tree[k];
     50     if(tree[k]){
     51         tree[k<<1]^=tree[k]; tree[k<<1|1]^=tree[k];
     52         tree[k]=0;
     53     }
     54     int mid=i+j>>1;
     55     if(x<=mid) return query(i,mid,k<<1);
     56     return query(mid+1,j,k<<1|1);
     57 }
     58 
     59 int lca(int u,int v){
     60     if(dep[u]>dep[v]) swap(u,v);
     61     for(int k=0; k<20; ++k){
     62         if((dep[v]-dep[u])>>k&1){
     63             v=fa[k][v];
     64         }
     65     }
     66     if(v==u) return u;
     67     for(int k=19; k>=0; --k){
     68         if(fa[k][u]!=fa[k][v]){
     69             u=fa[k][u];
     70             v=fa[k][v];
     71         }
     72     }
     73     return fa[0][u];
     74 }
     75 void init(){
     76     dfs();
     77     for(int i=1; i<20; ++i){
     78         for(int j=1; j<=n; ++j){
     79             int t=fa[i-1][j];
     80             if(t) fa[i][j]=fa[i-1][t];
     81         }
     82     }
     83     for(N=1; N<odr; N<<=1);
     84     for(int i=1; i<=n; ++i){
     85         x=l[i]; y=l[i]; z=val[i];
     86         update(1,N,1);
     87     }
     88 }
     89 int main(){
     90     int q,a,b;
     91     char op[11];
     92     memset(head,-1,sizeof(head));
     93     scanf("%d",&n);
     94     for(int i=1; i<=n; ++i){
     95         scanf("%d",stone+i);
     96     }
     97     for(int i=1; i<n; ++i){
     98         scanf("%d%d",&a,&b);
     99         addEdge(a,b);
    100         addEdge(b,a);
    101     }
    102     init();
    103     scanf("%d",&q);
    104     while(q--){
    105         scanf("%s%d%d",op,&a,&b);
    106         if(op[0]=='Q'){
    107             int res;
    108             x=l[a]; res=query(1,N,1);
    109             x=l[b]; res^=query(1,N,1);
    110             res^=stone[lca(a,b)];
    111             if(res) puts("Yes");
    112             else puts("No");
    113         }else{
    114             x=l[a]; y=r[a]; z=b^stone[a];
    115             update(1,N,1);
    116             stone[a]=b;
    117         }
    118     }
    119     return 0;
    120 }
  • 相关阅读:
    解决 Mac launchpad 启动台 Gitter 图标无法删除的问题
    React 与 React-Native 使用同一个 meteor 后台
    解决 React-Native mac 运行报错 error Failed to build iOS project. We ran "xcodebuild" command but it exited with error code 65. To debug build logs further, consider building your app with Xcode.app, by ope
    一行命令更新所有 npm 依赖包
    swift学习笔记
    IOS语言总结
    focusSNS学习笔记
    别小看锤子,老罗真的很认真
    windowsphone开发页面跳转到另一个dll中的页面
    【令人振奋】【转】微软潘正磊谈DevOps、Visual Studio 2013新功能、.NET未来
  • 原文地址:https://www.cnblogs.com/WABoss/p/4886918.html
Copyright © 2011-2022 走看看