zoukankan      html  css  js  c++  java
  • NewTrain1 T7: Nim

    题目分析

    关于Nim游戏,当所有堆异或起来为0时,必输,否则有必胜方法。

    所以,问题就转化成了在线询问树上一条道路上点权的异或值并支持修改。

    在树上的询问不好搞,所以我们使用bfs序将原树转化成一段区间。

    对于一次查询,也就转化成了一段区间的异或和。

    考虑一个点会影响哪个区间,已知,就是访问到它的时刻到遍历完它的所有子树之后再回来的那个时刻。

    所以,我们记录一个点初次访问和离开的bfs序,在树状数组上查询即可。(查询时因为树状数组维护的是他到根的异或和,这时两点的Lca被异或掉了,所以要再异或一下Lca的值)

    那么怎么处理修改呢?

    因为是异或,所以对于一个点,再更新一遍它就等于把这个点删掉。所以我们用原值更新一下这个点,再用新的值更新就行了。

      1 #include<bits/stdc++.h>
      2 #define INTMAX 2147483647LL
      3 #define PII pair<int,int>
      4 #define MK make_pair
      5 #define re register
      6 using namespace std;
      7 typedef long long ll;
      8 const double Pi=acos(-1.0);
      9 const int Inf=0x3f3f3f3f;
     10 const int MAXN=5e5+10; 
     11 inline int read(){
     12     re int x=0,f=1,ch=getchar();
     13     while(!isdigit(ch))f=ch=='-'?-1:1,ch=getchar();
     14     while(isdigit(ch))x=x*10+ch-48,ch=getchar();
     15     return x*f;
     16 }
     17 inline ll readll(){
     18     re ll x=0,f=1,ch=getchar();
     19     while(!isdigit(ch))f=ch=='-'?-1:1,ch=getchar();
     20     while(isdigit(ch))x=x*10+ch-48,ch=getchar();
     21     return x*f;
     22 }
     23 
     24 struct Edge{
     25     int to,nxt;
     26 }e[MAXN<<1];
     27 int cnt,head[MAXN];
     28 inline void add_edge(int u,int v){
     29     e[++cnt].to=v;e[cnt].nxt=head[u];head[u]=cnt;
     30 }
     31 int n,m;
     32 int bse[25],BIT[MAXN];
     33 int a[MAXN];
     34 int tim,l[MAXN],r[MAXN];
     35 int dep[MAXN],fa[MAXN][25];
     36 char ch[5];
     37 inline void dfs(int x){
     38     for(int i=1;i<=20;++i)
     39         if(dep[x]>=bse[i])
     40             fa[x][i]=fa[fa[x][i-1]][i-1];
     41         else
     42             break;
     43     l[x]=++tim;
     44     for(int i=head[x],y;i;i=e[i].nxt){
     45         y=e[i].to;
     46         if(y!=fa[x][0]){
     47             dep[y]=dep[x]+1;fa[y][0]=x;
     48             dfs(y);
     49         }
     50     }
     51     r[x]=tim;
     52 }
     53 inline int lowbit(int x){return x&(-x);}
     54 inline void Update(int x,int v){for(int i=x;i<=n;i+=lowbit(i)) BIT[i]^=v;}
     55 inline int Query(int x){int res=0;for(int i=x;i;i-=lowbit(i))res^=BIT[i];return res;}
     56 inline int Get_lca(int x,int y){
     57     if(dep[x]<dep[y]) swap(x,y);
     58     int tmp=dep[x]-dep[y];
     59     for(int i=0;i<=20;++i)
     60         if(bse[i]&tmp)
     61             x=fa[x][i];
     62     for(int i=20;i>=0;--i)
     63         if(fa[x][i]!=fa[y][i])
     64             x=fa[x][i],y=fa[y][i];
     65     if(x==y) return x;
     66     return fa[x][0];
     67 }
     68 int main(){
     69     bse[0]=1;for(int i=1;i<=21;++i) bse[i]=bse[i-1]<<1;
     70     n=read();
     71     for(int i=1;i<=n;++i) a[i]=read();
     72     for(int i=1,u,v;i<n;++i){
     73         u=read();v=read();
     74         add_edge(u,v);
     75         add_edge(v,u);
     76     }
     77     dfs(1);
     78     //cout<<111<<endl;
     79     for(int i=1;i<=n;++i){
     80         Update(l[i],a[i]);
     81         Update(r[i]+1,a[i]);
     82     }
     83     //cout<<2<<endl;
     84     m=read();
     85     while(m--){
     86         scanf("%s",ch);
     87         int x=read(),y=read();
     88         if(ch[0]=='Q'){
     89             int lca=Get_lca(x,y);
     90             int res=Query(l[x])^Query(l[y])^a[lca];
     91             puts(res?"Yes":"No");
     92         }
     93         else{
     94             Update(l[x],a[x]);Update(r[x]+1,a[x]);
     95             a[x]=y;
     96             Update(l[x],a[x]);Update(r[x]+1,a[x]);
     97         }
     98     } 
     99     return 0;
    100 } 
  • 相关阅读:
    leetcode231 2的幂 leetcode342 4的幂 leetcode326 3的幂
    leetcode300. Longest Increasing Subsequence 最长递增子序列 、674. Longest Continuous Increasing Subsequence
    leetcode64. Minimum Path Sum
    leetcode 20 括号匹配
    算法题待做
    leetcode 121. Best Time to Buy and Sell Stock 、122.Best Time to Buy and Sell Stock II 、309. Best Time to Buy and Sell Stock with Cooldown 、714. Best Time to Buy and Sell Stock with Transaction Fee
    rand7生成rand10,rand1生成rand6,rand2生成rand5(包含了rand2生成rand3)
    依图
    leetcode 1.Two Sum 、167. Two Sum II
    从分类,排序,top-k多个方面对推荐算法稳定性的评价
  • 原文地址:https://www.cnblogs.com/LI-dox/p/11267234.html
Copyright © 2011-2022 走看看