Codefores 932D Tree

Posted xuzihanllaa

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codefores 932D Tree相关的知识,希望对你有一定的参考价值。

原题传送门

一道题意很复杂的题目,为了表达一句话的意思,用了四句话去描述,纯粹为了误导

大致题意:一棵树,每个结点i会有一个权值weighti,初始时只有一个权值为0的根节点1。给定Q(Q≤4*105)个操作,操作分两类:

1.1 p q,表示新建结点cnt+1,权值为q,该结点与p结点连边。

2.2 p q,表示求最长的序列P,满足P1=p,对i>1,都有:Pi是Pi-1与根结点路径上离Pi-1最近的权值不小于weighti的点,且所有weightPi加起来(有点拗口,看不懂的可以看原题描述)

具体有一些区别:其实就是强制在线辣,请以实际描述为准。

 

分析:很明显能看出一些不变的东西:结点只增不减,而后续结点的加入不会影响之前结点的性质,也就是说,一个结点的信息在他加入的时候就已经完全确定,而这些信息都能由祖先的信息推出,于是想到倍增。具体维护两个信息st_par和st_sum(我代码里省事把st_par简写为st,st_sum简写为sum),其中st_par[i][j]表示从结点i向上“跳”2j步的结点编号,这里“跳”一步指的是进行一次寻找“到根结点路径上第一个不小于当前结点权值的结点”的操作,st_sum[i][j]表示跳的过程中所有经过结点(不包括起点)的权值之和。能这样维护的原因是:操作2中的序列其实是唯一的,我只要能快速维护找到下一个结点的操作就行。这样倍增的轮廓就出来了,但是还有一件事要解决:第一步也就是st[i][0]怎么计算?这里就要用到二分的思想了:设tmp为i的父亲,利用二分锁定离i最近的符合要求的点,具体怎么实现就不用多说了,我想说的是我原本的写法:我原来写的是由i的父亲一步一步按st[tmp][0]的方式往上跳,实测两种写法没有任何时间上的差别,但是复杂度肯定是不一样的。。

 

代码随便看看。。

技术分享图片
  1 /*    Codeforces 932D Tree
  2     1st Edition:2018.2.15 Thursday
  3     2nd Edition:2018.2.16 Friday
  4     Algorithm:倍增
  5 */
  6 #include <iostream>
  7 #include <cstdio>
  8 #include <algorithm>
  9 #include <cmath>
 10 #include <cstring>
 11 #include <vector>
 12 #include <map>
 13 #include <set>
 14 #include <bitset>
 15 #include <queue>
 16 #include <deque>
 17 #include <stack>
 18 #include <iomanip>
 19 #include <cstdlib>
 20 #include <ctime>
 21 #include <cctype>
 22 using namespace std;
 23 
 24 #define is_lower(c) (c>=‘a‘ && c<=‘z‘)
 25 #define is_upper(c) (c>=‘A‘ && c<=‘Z‘)
 26 #define is_alpha(c) (is_lower(c) || is_upper(c))
 27 #define is_digit(c) (c>=‘0‘ && c<=‘9‘)
 28 #define stop system("PAUSE")
 29 #define ForG(a,b,c) for(rg int (a)=c.head[b];(a);(a)=c.E[a].nxt)
 30 #define For(a,b,c) for(rg int (a)=(b);(a)<=(c);++a)
 31 #define min(a,b) ((a)<(b)?(a):(b))
 32 #define max(a,b) ((a)>(b)?(a):(b))
 33 #define shl(x,y) ((x)<<(y))
 34 #define shr(x,y) ((x)>>(y))
 35 #define mp make_pair
 36 #define pb push_back
 37 #define rg register
 38 #ifdef ONLINE_JUDGE
 39 #define hash rename_hash
 40 #define next rename_next
 41 #define prev rename_prev
 42 #endif
 43 typedef long long ll;
 44 typedef unsigned long long ull;
 45 typedef pair<int,int> pii;
 46 typedef pair<ll,ll> pll;
 47 typedef vector<int> vi;
 48 typedef double db;
 49 const ll inf=1000000007LL;
 50 const db EPS=1e-14;
 51 const ll inf_ll=(ll)1e18;
 52 const ll maxn=400005LL;
 53 const ll mod=1000000007LL;
 54 
 55 int n,cnt;
 56 ll last;
 57 ll weight[maxn],sum[maxn][20];
 58 int par[maxn],st[maxn][20];
 59 
 60 int main(){
 61     scanf("%d",&n);
 62     cnt=1;
 63     while(n--){
 64         ll opt,p,q;
 65         scanf("%I64d %I64d %I64d",&opt,&p,&q);
 66         p^=last;q^=last;
 67         if(opt^2){
 68             par[++cnt]=p;
 69             weight[cnt]=q;
 70             int tmp=p;
 71             if(weight[tmp]<q){
 72                 for(int i=19;i+1;--i) if(st[tmp][i] && weight[st[tmp][i]]<q){
 73                     tmp=st[tmp][i];
 74                 }
 75                 tmp=st[tmp][0];
 76             }
 77             st[cnt][0]=tmp;
 78             sum[cnt][0]=weight[tmp];
 79             For(i,1,19) if(st[cnt][i-1] && st[st[cnt][i-1]][i-1]){
 80                 st[cnt][i]=st[st[cnt][i-1]][i-1];
 81                 sum[cnt][i]=sum[cnt][i-1]+sum[st[cnt][i-1]][i-1];
 82             }
 83         }else{
 84             ll nowsum=weight[p];
 85             if(nowsum>q){
 86                 puts("0");
 87                 last=0;
 88                 continue;
 89             }
 90             int now=p,res=1;
 91             for(int i=19;i>=0;--i) if(st[now][i] && sum[now][i]+nowsum<=q){
 92                 nowsum+=sum[now][i];
 93                 now=st[now][i];
 94                 res+=shl(1,i);
 95             }
 96             printf("%d\n",res);
 97             last=(ll)res;
 98         }
 99     }
100     return 0;
101 }
View Code

 

以上是关于Codefores 932D Tree的主要内容,如果未能解决你的问题,请参考以下文章

CF932D Tree

CF932D Tree 树上倍增

Codefores 1025D Recovering BST

CodeFores Round53(div.2) D.Berland Fair

添加片段时的 FlyOut 菜单设计问题

我在对象数组上使用 ngFor,而在 html 中数据未显示