BZOJ3435: [Wc2014]紫荆花之恋(替罪羊树,Treap)
Description
强强和萌萌是一对好朋友。有一天他们在外面闲逛,突然看到前方有一棵紫荆树。这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来。仔细看看的话,这个大树实际上是一个带权树。每个时刻它会长出一个新的叶子节点。每个节点上有一个可爱的小精灵,新长出的节点上也会同时出现一个新的小精灵。小精灵是很萌但是也很脆弱的生物,每个小精灵 i 都有一个感受能力值Ri ,小精灵 i, j 成为朋友当且仅当在树上 i 和 j 的距离 dist(i,j) ≤ Ri + Rj,其中 dist(i, j)表示在这个树上从 i 到 j 的唯一路径上所有边的边权和。强强和萌萌很好奇每次新长出一个叶子节点之后,这个树上总共有几对朋友。
我们假定这个树一开始为空,节点按照加入的顺序从 1开始编号。由于强强非常好奇, 你必须在他每次出现新节点后马上给出总共的朋友对数,不能拖延哦。
Input
共有 n + 2 行。
第一行包含一个正整数,表示测试点编号。
第二行包含一个正整数 n ,表示总共要加入的节点数。
我们令加入节点前的总共朋友对数是 last_ans,在一开始时它的值为0。
接下来 n 行中第 i 行有三个数 ai, bi, ri,表示节点 i 的父节点的编号为 ai xor (last_ans mod 10^9) (其中xor 表示异或,mod 表示取余,数据保证这样操作后得到的结果介于 1到i – 1之间),与父节点之间的边权为 ci,节点 i 上小精灵的感受能力值为ri。
注意 a1 = c1 = 0,表示 1 号点是根节点,对于 i > 1,父节点的编号至少为1。
Output
包含 n 行,每行输出1 个整数, 表示加入第 i 个点之后,树上有几对朋友。
Sample Input
5
0 0 6
1 2 4
0 9 4
0 5 5
0 2 4
Sample Output
1
2
4
7
解题思路:
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define lll tr[spc].ls
#define rrr tr[spc].rs
typedef long long lnt;
const double alpha=0.77;
struct pnt{
int hd;
int F;
int T;
int dp;
int val;
int wgt;
int wgt_;
int fa[];
int root;
int root_;
lnt dis;
bool vis;
}p[];
struct ent{
int twd;
int lst;
int vls;
}e[];
struct trnt{
int ls;
int rs;
int val;
int wgt;
int rnd;
}tr[],BLANK_TRNT;
int siz;
int top;
int cnt;
int tot;
int tms;
int root;
int maxval;
int n,test_no;
lnt lastans;
int bin[];
void del(int &spc)
{
if(!spc)return ;
bin[++top]=spc;
spc=;
return ;
}
int newp(void)
{
if(top)
{
int spc=bin[top--];
if(lll)bin[++top]=lll;
if(rrr)bin[++top]=rrr;
return spc;
}
return ++siz;
}
int apply(int v)
{
int spc=newp();
tr[spc]=BLANK_TRNT;
tr[spc].val=v;
tr[spc].rnd=rand();
tr[spc].wgt=;
return spc;
}
void pushup(int spc)
{
tr[spc].wgt=tr[lll].wgt+tr[rrr].wgt+;
return ;
}
void lturn(int &spc)
{
int tmp=lll;
lll=tr[tmp].rs;
tr[tmp].rs=spc;
pushup(spc);
pushup(tmp);
spc=tmp;
return ;
}
void rturn(int &spc)
{
int tmp=rrr;
rrr=tr[tmp].ls;
tr[tmp].ls=spc;
pushup(spc);
pushup(tmp);
spc=tmp;
}
void insert(int &spc,int v)
{
if(!spc)
{
spc=apply(v);
return ;
}
if(tr[spc].val<v)
{
insert(rrr,v);
if(tr[rrr].rnd<tr[spc].rnd)rturn(spc);
}else{
insert(lll,v);
if(tr[lll].rnd<tr[spc].rnd)lturn(spc);
}
pushup(spc);
return ;
}
int rank(int spc,int v)
{
int ans=;
while(spc)
{
if(tr[spc].val<v)
{
ans+=tr[lll].wgt+;
spc=rrr;
}else spc=lll;
}
return ans;
}
//------------^Treap
void ade(int f,int t,int v)
{
if(!f||!t)return ;
cnt++;
e[cnt].twd=t;
e[cnt].vls=v;
e[cnt].lst=p[f].hd;
p[f].hd=cnt;
return ;
}
void decode(int &tmp_a)
{
tmp_a^=(lastans%);
return ;
}
int lca(int x,int y)
{
if(p[x].dp<p[y].dp)std::swap(x,y);
for(int i=;i>=;i--)
if(p[p[x].fa[i]].dp>=p[y].dp)
x=p[x].fa[i];
if(x==y)return x;
for(int i=;i>=;i--)
{
if(p[x].fa[i]!=p[y].fa[i])
{
x=p[x].fa[i];
y=p[y].fa[i];
}
}
return p[x].fa[];
}
lnt dis(int x,int y)
{
return p[x].dis+p[y].dis-p[lca(x,y)].dis*;
}
void kill(int x,int f,int t)
{
tot++;
p[x].wgt_=;
p[x].T=tms;
p[x].vis=false;
del(p[x].root);
del(p[x].root_);
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to==f||p[to].wgt_>t)continue;
kill(to,x,t);
}
return ;
}
void grc_dfs(int x,int f)
{
p[x].wgt=;
int maxs=;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to==f||p[to].vis)continue;
grc_dfs(to,x);
p[x].wgt+=p[to].wgt;
maxs=std::max(maxs,p[to].wgt);
}
maxs=std::max(maxs,tot-p[x].wgt);
if(maxs<maxval)
{
root=x;
maxval=maxs;
}
return ;
}
void bin_dfs(int x,int F)
{
p[x].F=F;
p[x].vis=true;
int tmpv=tot;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].vis)continue;
if(p[x].wgt>p[to].wgt)tot=p[to].wgt;
else tot=tmpv-p[x].wgt;
root=;
maxval=0x3f3f3f3f;
grc_dfs(to,to);
bin_dfs(root,x);
}
return ;
}
void relive(int x,int f,int F)
{
for(int i=x;i!=F;i=p[i].F)
{
p[i].wgt_++;
insert(p[i].root,dis(x,i)-p[x].val);
if(!p[i].F)break;
insert(p[i].root_,dis(p[i].F,x)-p[x].val);
}
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].T!=tms||to==f)continue;
relive(to,x,F);
}
return ;
}
void rebuild(int x)
{
tms++;
int F=p[x].F;
tot=;
root=;
maxval=0x3f3f3f3f;
kill(x,x,p[x].wgt_);
grc_dfs(x,x);
bin_dfs(root,F);
relive(x,x,F);
return ;
}
void T_insert(int x)
{
int plc=;
p[x].wgt_=;
insert(p[x].root,-p[x].val);
for(int i=x;p[i].F;i=p[i].F)
{
insert(p[p[i].F].root,dis(p[i].F,x)-p[x].val);
insert(p[i].root_,dis(p[i].F,x)-p[x].val);
p[p[i].F].wgt_++;
if(1.00*p[i].wgt_>alpha*p[p[i].F].wgt_)plc=p[i].F;
}
if(plc)rebuild(plc);
return ;
}
lnt T_query(int x)
{
lnt ans=rank(p[x].root,p[x].val+)-;
for(int i=x;p[i].F;i=p[i].F)
{
ans+=rank(p[p[i].F].root,p[x].val-dis(p[i].F,x)+);
ans-=rank(p[i].root_,p[x].val-dis(p[i].F,x)+);
}
return ans;
}
int main()
{
scanf("%d",&test_no);
scanf("%d",&n);
for(int i=;i<=n;i++)
{
p[i].vis=true;
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
decode(a);
p[i].F=a;
p[i].val=c;
p[i].dp=p[a].dp+;
p[i].dis=p[a].dis+b;
if(i!=)p[i].fa[]=a;
else p[i].fa[]=;
for(int j=;j<=;j++)p[i].fa[j]=p[p[i].fa[j-]].fa[j-];
ade(i,a,b);ade(a,i,b);
T_insert(i);
lastans+=T_query(i);
printf("%lld\n",lastans);
}
return ;
}
BZOJ3435: [Wc2014]紫荆花之恋(替罪羊树,Treap)的更多相关文章
- bzoj 3435: [Wc2014]紫荆花之恋 替罪羊树维护点分治 && AC400
3435: [Wc2014]紫荆花之恋 Time Limit: 240 Sec Memory Limit: 512 MBSubmit: 159 Solved: 40[Submit][Status] ...
- BZOJ 3435 / Luogu 3920 [WC2014]紫荆花之恋 (替罪羊树 动态点分治 套 Treap)
题意 略 分析 引用PoPoQQQ的话 吾辈有生之年终于把这道题切了...QAQ (蒟蒻狂笑) Orz PoPoQQQ,我又抄PoPoQQQ的题解了 - 突然发现有旋Treap没那么难写 学习了一波C ...
- BZOJ3435[Wc2014]紫荆花之恋——动态点分治(替罪羊式点分树套替罪羊树)
题目描述 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来.仔细看看的话,这个大树实际上是一个带权树.每 ...
- bzoj3435 [Wc2014]紫荆花之恋(动态点分治+替罪羊树)
传送门(权限) 传送门(非权限) 题解 我终终终终终终于做出来啦!!! 作为一个没有学过替罪羊树的蒟蒻现场学了一下替罪羊树,作为一个平衡树都写数组版本的看着大佬的指针题解无语只能硬去理解然后照着抄了一 ...
- bzoj3435 [Wc2014]紫荆花之恋
如果这棵树不变的话,就是一个裸的点分树套平衡树,式子也很好推$di+dj<=ri+rj$,$ri-di>=dj-rj$ 平衡树维护$dj-rj$,然后查$ri-di$的$rank$即可. ...
- 【BZOJ3435】[Wc2014]紫荆花之恋 替罪点分树+SBT
[BZOJ3435][Wc2014]紫荆花之恋 Description 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从 ...
- BZOJ 3435: [Wc2014]紫荆花之恋
二次联通门 : BZOJ 3435: [Wc2014]紫荆花之恋 二次联通门 : luogu P3920 [WC2014]紫荆花之恋 /* luogu P3920 [WC2014]紫荆花之恋 怀疑人生 ...
- 【bzoj3435】[Wc2014]紫荆花之恋 替罪点分树套SBT
题目描述 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来.仔细看看的话,这个大树实际上是一个带权树.每 ...
- [WC2014]紫荆花之恋(动态点分治+替罪羊思想)
题目描述 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来.仔细看看的话,这个大树实际上是一个带权树.每 ...
随机推荐
- Homebrew命令具体解释
Homebrew命令具体解释 作者:chszs,未经博主同意不得转载.经许可的转载需注明作者和博客主页:http://blog.csdn.net/chszs 一.安装Homebrew Shell环境下 ...
- RabbitMQserver配置文件
RabbitMQ的server配置设置.我做了改动,改动例如以下: {tcp_listeners, [5672]}, {loopback_users, ["elite"]} 其他的 ...
- HDU 5303 Delicious Apples (2015多校第二场 贪心 + 枚举)
Delicious Apples Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Other ...
- Android开发之EditText 详解(addTextChangedListener监听用户输入状态)
为了实现像qq或者微信输入框的效果,当在 EditText输入字符串时发送按钮显示,当输入框字符消除掉时按钮改变.所以这时候我就要用到addTextChangedListener 用它来监听用户输入状 ...
- 智课雅思短语---五、 in contrast / on the contrary
智课雅思短语---五. in contrast / on the contrary 一.总结 一句话总结:相反 in contrast / on the contrary. 1.replace/ su ...
- [JZOJ3382] [NOIP2013模拟] 七夕祭 解题报告
Description 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子.于是TYVJ今年举办了一次线下七夕祭.Vani同学今年成功邀请到了cl同学陪他来共度七夕,于是他们决定去TYVJ七夕祭游玩. ...
- C++字节对齐与结构体大小计算
转载注明出处:http://pppboy.blog.163.com/blog/static/30203796201082494026399/ 感谢原创博主的辛勤成果. 说明: 结构体的sizeof值, ...
- PostgreSQL Replication之第九章 与pgpool一起工作(5)
9.5 检查复制 如果所有的节点都处于开机并运行的状态.我们就可以在集群上运行我们的第一个操作了.在我们的例子中,我们将简单地连接到pgpool并创建一个新的数据库.createdb 是一个命令行工具 ...
- RMAN备份脚本
单机环境全备 export ORACLE_BASE=/oracle export ORACLE_HOME=$ORACLE_BASE/product/10.2.0/db_1 export ORA ...
- iOS——扬声器与听筒的切换
1.扬声器模式: NSError *error; [[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPor ...