zoukankan      html  css  js  c++  java
  • Tree CodeForces -932D

    错误记录:如下注释语句

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 typedef long long LL;
     5 LL log2n=19,cnt=1;
     6 LL anc[400010][20],maxv[400010][20],v[400010];
     7 LL anc2[400010][20],sum[400010][20];
     8 LL pow2[]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288};
     9 //maxv[i][j]指i到其2^j级祖先的路径上点权最大值,含2^j级祖先,不含i
    10 //sum[i][j]指i到其2^j级祖先的路径上点权之和,含祖先,不含i
    11 LL Q,last;
    12 int main()
    13 {
    14     LL i,idx,p,q,t,ans;
    15     v[0]=1e15+1;
    16     for(i=0;i<=log2n;i++)    maxv[1][i]=maxv[0][i]=sum[1][i]=sum[0][i]=1e15+1;
    17     scanf("%lld",&Q);
    18     while(Q--)
    19     {
    20         scanf("%lld%lld%lld",&idx,&p,&q);
    21         p^=last;q^=last;
    22         //printf("%lld %lld
    ",p,q);
    23         if(idx==1)
    24         {
    25             v[++cnt]=q;anc[cnt][0]=p;maxv[cnt][0]=v[anc[cnt][0]];
    26             //putchar('a');printf("%d %d ",0,maxv[cnt][0]);
    27             for(i=1;i<=log2n;i++)
    28             {
    29                 anc[cnt][i]=anc[anc[cnt][i-1]][i-1];
    30                 maxv[cnt][i]=max(maxv[cnt][i-1],maxv[anc[cnt][i-1]][i-1]);
    31                 //printf("%d %d ",i,maxv[cnt][i]);
    32             }
    33             //putchar('b');
    34             for(t=cnt,i=log2n;i>=0;i--)
    35                 if(maxv[t][i]<v[cnt])
    36                     t=anc[t][i];
    37             anc2[cnt][0]=anc[t][0];sum[cnt][0]=v[anc2[cnt][0]];
    38             //printf("%d %d
    ",cnt,nxt[cnt]);
    39             //printf("%lld %lld ",0LL,sum[cnt][0]);
    40             for(i=1;i<=log2n;i++)
    41             {
    42                 anc2[cnt][i]=anc2[anc2[cnt][i-1]][i-1];
    43                 sum[cnt][i]=sum[cnt][i-1]+sum[anc2[cnt][i-1]][i-1];
    44                 //printf("%lld %lld ",i,sum[cnt][i]);
    45             }
    46             //putchar('c');
    47         }
    48         else
    49         {
    50             q-=v[p];ans=1;if(q<0){ans=0;goto xxx;}
    51             for(t=p,i=log2n;i>=0;i--)
    52                 if(sum[t][i]<=q)
    53                 {
    54                     //t=anc2[t][i];
    55                     q-=sum[t][i];ans+=pow2[i];//ans++
    56                     t=anc2[t][i];
    57                 }
    58             xxx:last=ans;
    59             printf("%lld
    ",ans);
    60         }
    61     }
    62     return 0;
    63 }
    View Code
    另外,不能看到要加点就想动态树(不会)什么的,比如这道题,虽然要加点,但是仅此而已,用不到那些东西,只需要加入点时倍增求出要维护的值就行了。

    对于原树,每加入一个节点u求出maxv(含义见程序),然后由这个新节点u向上倍增找到其祖先节点v,使得u到v的路径上所有点(不含u,含v)权值的最大值小于u的权值,且v深度最小。那么v的父节点就是u向上一级一级跳时第一个能访问到的权值大于等于u的节点,记为nxt[u](程序中省略,直接记为anc2[u][0])。

    这样子,对于每个节点u(除了1号)都能得到nxt[u],把nxt[u]当做u的父节点,形成一棵新的树,那么查询转化为给定一个节点u,在新树上找到u的祖先节点v,使得u到v的路径上所有点(含u和v)权值之和小于等于x,且v的深度最小,输出u到v的路径上点数(含u和v)。(当然也可能u的权值就超过x了,那么输出0,要特判)。仍然倍增解决即可。

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 typedef long long LL;
     5 LL log2n=19,cnt=1;
     6 LL anc[400010][20],maxv[400010][20],v[400010];
     7 LL anc2[400010][20],sum[400010][20];
     8 //maxv[i][j]指i到其2^j级祖先的路径上点权最大值,含2^j级祖先,不含i
     9 //sum[i][j]指i到其2^j级祖先的路径上点权之和,含祖先,不含i
    10 LL Q,last;
    11 int main()
    12 {
    13     LL i,idx,p,q,t,ans;
    14     v[0]=1e15+1;
    15     for(i=0;i<=log2n;i++)    maxv[1][i]=maxv[0][i]=sum[1][i]=sum[0][i]=1e15+1;
    16     scanf("%lld",&Q);
    17     while(Q--)
    18     {
    19         scanf("%lld%lld%lld",&idx,&p,&q);
    20         p^=last;q^=last;
    21         if(idx==1)
    22         {
    23             v[++cnt]=q;anc[cnt][0]=p;maxv[cnt][0]=v[anc[cnt][0]];
    24             for(i=1;i<=log2n;i++)
    25             {
    26                 anc[cnt][i]=anc[anc[cnt][i-1]][i-1];
    27                 maxv[cnt][i]=max(maxv[cnt][i-1],maxv[anc[cnt][i-1]][i-1]);
    28             }
    29             for(t=cnt,i=log2n;i>=0;i--)
    30                 if(maxv[t][i]<v[cnt])
    31                     t=anc[t][i];
    32             anc2[cnt][0]=anc[t][0];sum[cnt][0]=v[anc2[cnt][0]];
    33             for(i=1;i<=log2n;i++)
    34             {
    35                 anc2[cnt][i]=anc2[anc2[cnt][i-1]][i-1];
    36                 sum[cnt][i]=sum[cnt][i-1]+sum[anc2[cnt][i-1]][i-1];
    37             }
    38         }
    39         else
    40         {
    41             q-=v[p];ans=1;if(q<0){ans=0;goto xxx;}
    42             for(t=p,i=log2n;i>=0;i--)
    43                 if(sum[t][i]<=q)
    44                 {
    45                     q-=sum[t][i];ans+=(1LL<<i);
    46                     t=anc2[t][i];
    47                 }
    48             xxx:last=ans;
    49             printf("%lld
    ",ans);
    50         }
    51     }
    52     return 0;
    53 }
  • 相关阅读:
    Windows2012中安装PHP-5.6.20+Apache httpd2.4.18+Composer+Laravel+MySQL5.7
    CentOS7安装使用MySQL
    使用passenger在Centos7部署Puma+Nginx+Ruby on Rails
    DOS和UNIX文本文件之间相互转换的方法
    CentOS7安装vim7.4
    Python多版本共存之pyenv
    我的Shell + VIM配置
    CentOS7安装Python3.5
    CentOS7系统下搭建Jenkins环境
    Windows系统下搭建Jenkins环境
  • 原文地址:https://www.cnblogs.com/hehe54321/p/cf-932d.html
Copyright © 2011-2022 走看看