zoukankan      html  css  js  c++  java
  • hdu5390 tree

      先求出dfs序,然后建立线段树,线段树每个节点套一个set。

      修改操作只需要改被子树区间完全覆盖的线段树节点,将其节点中set的原来的值删除,加入新值。

      询问操作查询单点到根的所有节点上的set中与查询值异或起来最大的那个。

      查询set中的数与x异或的最大值,可以从高位到低位枚举二进制位,根据x的二进制位,查询一些set中数值的存在情况,例如加入x的二进制第y位为1,那么如果set中存在第y位为0的数字,明显可以使得答案更大。下面代码中这段的代码类似于二分。

      时间复杂度O(nlogn^3)

      

      代码

      1 #include<cstdio>
      2 #include<set>
      3 #include<algorithm>
      4 #include<cstring>
      5 #define N 500010
      6 using namespace std;
      7 int n,m,i,a,b,typ;
      8 int dp,p[N],pre[N],tt[N];
      9 int tot,L[N],R[N],l[N],r[N],v[N],stack[N],deep,flag;
     10 multiset<int> Set[N];
     11 void link(int x,int y)
     12 {
     13     dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;
     14 }
     15 void dfs()
     16 {
     17     int i;
     18     while (deep)
     19     {
     20         if (L[stack[deep]]==0)
     21         {
     22             tot++;
     23             L[stack[deep]]=tot;
     24         }
     25         if (p[stack[deep]])
     26         {
     27             i=p[stack[deep]];
     28             deep++;stack[deep]=tt[i];
     29             p[stack[deep-1]]=pre[i];
     30         }
     31         else
     32         {
     33             R[stack[deep]]=tot;
     34             deep--;
     35         }
     36     }
     37 }
     38 void build(int x,int a,int b)
     39 {
     40     int m;
     41     l[x]=a;r[x]=b;
     42     Set[x].clear();
     43     Set[x].insert(-1);
     44     Set[x].insert(1<<30);
     45     if (b-a>1)
     46     {
     47         m=(a+b)>>1;
     48         build(2*x,a,m);
     49         build(2*x+1,m,b);
     50     }
     51 }
     52 void change(int x,int a,int b,int c,int d)
     53 {
     54     if ((a<=l[x])&&(r[x]<=b))
     55     {
     56         Set[x].insert(d);
     57         if (flag)
     58         Set[x].erase(c);
     59         return;
     60     }
     61     int m=(l[x]+r[x])>>1;
     62     if (a<m) change(2*x,a,b,c,d);
     63     if (m<b) change(2*x+1,a,b,c,d);
     64 }
     65 int Q(int x,int y)
     66 {
     67     int l,r,m,p,q;
     68     if (Set[x].size()==2) return 0;
     69     l=0;r=(1<<30)-1;
     70     while (l!=r)
     71     {
     72         m=(l+r)>>1;
     73         multiset<int>::iterator it=Set[x].upper_bound(m);
     74         p=*it;
     75         q=*(--it);
     76         if (p>r)
     77             r=m;
     78         else
     79         if (q<l)
     80             l=m+1;
     81         else
     82         {
     83             if ((l^y)>((m+1)^y))
     84             r=m;
     85             else
     86             l=m+1;
     87         }
     88     }
     89     return l^y;
     90 }
     91 int query(int x,int a,int b,int c)
     92 {
     93     int ans=Q(x,c);
     94     if ((a<=l[x])&&(r[x]<=b))
     95     return ans;
     96     int m=(l[x]+r[x])>>1;
     97     if (a<m) ans=max(ans,query(2*x,a,b,c));
     98     if (m<b) ans=max(ans,query(2*x+1,a,b,c));
     99     return ans;
    100 }
    101 int main()
    102 {
    103     int test;
    104     scanf("%d",&test);
    105     while (test--)
    106     {
    107     scanf("%d%d",&n,&m);
    108     dp=0;
    109     for (i=1;i<=n;i++)
    110     {
    111         L[i]=0;
    112         p[i]=0;
    113     }
    114     for (i=2;i<=n;i++)
    115     {
    116         scanf("%d",&a);
    117         link(a,i);
    118     }
    119     tot=0;
    120     deep=1;stack[1]=1;
    121     dfs();
    122 
    123     build(1,0,n);
    124     flag=0;
    125     for (i=1;i<=n;i++)
    126     {
    127         scanf("%d",&v[i]);
    128         change(1,L[i]-1,R[i],0,v[i]);
    129     }
    130     flag=1;
    131     for (i=1;i<=m;i++)
    132     {
    133         scanf("%d",&typ);
    134         if (typ==0)
    135         {
    136             scanf("%d%d",&a,&b);
    137             change(1,L[a]-1,R[a],v[a],b);
    138             v[a]=b;
    139         }
    140         else
    141         {
    142             scanf("%d",&a);
    143             printf("%d
    ",query(1,L[a]-1,L[a],v[a]));
    144         }
    145     }
    146     }
    147 }
  • 相关阅读:
    数独
    面向对象程序设计课第七次作业
    面向对象程序设计课第六次作业
    软件工程课总结
    第四次作业:四则运算界面
    psp记录个人项目花费时间
    作业三:代码规范,代码复查
    编写一个能生成小学四则运算题目的运算
    目前流行的源程序版本管理软件和项目管理软件有哪些?有什么优缺点
    课程进度总结
  • 原文地址:https://www.cnblogs.com/fzmh/p/4731579.html
Copyright © 2011-2022 走看看