博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ICM Technex 2018 and Codeforces Round #463 (Div. 1 + Div. 2, combined) ---d
阅读量:5096 次
发布时间:2019-06-13

本文共 1655 字,大约阅读时间需要 5 分钟。

 

最暴力的想法自然是,对于每一次询问,沿着父亲一点一点往上跳模拟。这样似乎并不能优化...

稍微好一点的想法是对于每一个点开一个nxt数组表示父亲中权值大于他的里面离他最近的在哪里,同样对于每一次询问模拟往上跳,每次加点模拟往上找,复杂度依旧没有变化,但为我们提供了一个思路,我们可以倍增啊!

首先我们对于2操作,我们记录sum[x][i]表示他的2^i个nxt的值的和是多少,这样我们就可以快速求出在总权值小于x的前提下最多能跳到哪里。

考虑如何求出这个数组。

定义nxt[x][i]为x的第2^i个nxt是谁。

对于每一次加点操作,我们记录fa[x][i]表示x的第2^i个父亲是谁,同时记录这些父亲中的最大值是多少。那么我们加入一个点时就可以快速求出第一个大于他的位置在哪里。即nxt[x][0],然后递推可以分别求出nxt[x][1],nxt[x][2].....沿途记录sum即可。

1 #include
2 #define LL long long 3 using namespace std; 4 const int inf=4e5+10; 5 int Q,siz,last; 6 int w[inf]; 7 int fa[inf][20],Max[inf][20]; 8 int nxt[inf][20]; 9 LL sum[inf][20];10 void get(int x,int y){11 fa[x][0]=y;12 Max[x][0]=w[y];13 for(int i=1;i<=19;i++){14 fa[x][i]=fa[fa[x][i-1]][i-1];15 Max[x][i]=max(Max[x][i-1],Max[fa[x][i-1]][i-1]);16 }17 int now=x;18 for(int i=19;i>=0;i--){19 if(Max[now][i]
y)return 0;31 int cnt=1;32 y-=w[x];33 for(int i=19;i>=0;i--){34 if(nxt[x][i]!=0&&sum[x][i]<=y){35 y-=sum[x][i];36 x=nxt[x][i];37 cnt+=p[i];38 }39 }40 return cnt;41 }42 int main()43 {44 scanf("%d",&Q);45 siz=1;46 p[0]=1;47 for(int i=1;i<=19;i++)p[i]=p[i-1]<<1;48 while(Q--){49 int opt;50 LL x,y;51 scanf("%d%lld%lld",&opt,&x,&y);52 x=x^last;y=y^last;53 if(opt==1){54 siz++;55 w[siz]=y;56 get(siz,x);57 }58 else {59 last=work(x,y);60 printf("%d\n",last);61 }62 }63 return 0;64 }
View Code

 

转载于:https://www.cnblogs.com/hyghb/p/8456335.html

你可能感兴趣的文章
病毒侵袭(hdu2896,ac自动机)
查看>>
浏览器请求页面时Etag和cache的区别
查看>>
Java 基础知识面试题
查看>>
【Visual Installer】如何注册自已的文件类型
查看>>
关于跳出循环
查看>>
文件拓展名/HTML转义字符/RGB颜色参考/网页字体参考
查看>>
Android常用的UI布局
查看>>
科研呢喃3-论科研选题
查看>>
python (2) 之 pyc
查看>>
TextInputLayout setError() setErrorEnable()
查看>>
HDD&Memory&CPU调度机制(I/O硬件性能瓶颈)
查看>>
city
查看>>
Weex 相关文章收集
查看>>
Android Ap 开发 设计模式第八篇:抽象工厂模式
查看>>
【查阅】教你使用SQL SERVER复制
查看>>
如何用C语言画一个圣诞树?
查看>>
REDIS源码中一些值得学习的技术细节02
查看>>
hrbust1758
查看>>
Java-Class-I:com.alibaba.fastjson.JSONObject
查看>>
Node.js:连接 MongoDB
查看>>