如果这棵树不变的话,就是一个裸的点分树套平衡树,式子也很好推$di+dj<=ri+rj$,$ri-di>=dj-rj$ 平衡树维护$dj-rj$,然后查$ri-di$的$rank$即可。

但是点分树如果极度不平衡也就没有什么意义了。所以利用替罪羊树的思想,当某个子树极度不平衡时,就重新找重心,重建点分树。时间复杂度$O(nlg^2n)$,无旋Treap被卡,有旋Treap常数十分优秀。

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define L 1<<20
char _buf[L],*SS,*TT,c;
const int BufS=,md=;
char buf[BufS],*inss=buf,*outs=buf,num[];
inline void pl(register long long a){
if(!a){*outs++='',*outs++='\n';return;}
register int tp=;while(a)num[tp++]=a%,a/=;
while(tp--)*outs++=num[tp]+'';*outs++='\n';
}
#define gc() (SS==TT&&(TT=(SS=_buf)+fread(_buf,1,L,stdin),SS==TT)?0:*SS++)
int get()
{
for(c=gc();c<''||c>'';c=gc());
int x=c^'';
for(c=gc();c>=''&&c<='';c=gc())x=x*+(c^'');
return x;
}
#define N 100050
int n;
long long ans;
namespace Treap{
#define tp pair<Node*,Node*>
struct Node{
Node *ch[];
int key,val,size;
void pushup(){
size=ch[]->size+ch[]->size+;
}
Node(int k);
}*null=new Node(),*root[N],*root1[N];
Node :: Node(int k){
key=k;val=rand();size=;
ch[]=ch[]=null;
}
void init(){
null->ch[]=null->ch[]=null;
null->key=null->val=null->size=;
for(int i=;i<=::n;i++)root[i]=root1[i]=null;
}
int getrank(Node *now,int x){
int ans=;
while(now!=null){
if(now->key<x)ans+=now->ch[]->size+,now=now->ch[];
else now=now->ch[];
}
return ans;
}
void rotate(Node *&x,int d){
Node *y=x->ch[d];
x->ch[d]=y->ch[d^];
y->ch[d^]=x;
x->pushup();y->pushup();
x=y;
}
void insert(Node *&rt,int x){
if(rt==null)rt=new Node(x);
else{
int d=x>rt->key;
insert(rt->ch[d],x);
if(rt->ch[d]->val<rt->val)rotate(rt,d);
}
rt->pushup();
}
void dfs(Node *rt){
if(rt==null)return;
dfs(rt->ch[]);
dfs(rt->ch[]);
delete rt;
}
}
int head[N],e=;
struct edge{
int v,next;
}ed[N<<];
void add(int u,int v){
ed[e].v=v;ed[e].next=head[u];
head[u]=e++;
}
int dep[N],val[N],fa[N][],r[N],w[N];
int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
for(int i=;~i;i--)
if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
if(x==y)return x;
for(int i=;~i;i--)
if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return fa[x][];
}
int dis(int x,int y){
return val[x]+val[y]-*val[lca(x,y)];
}
int size[N],maxn[N],root,sum;
bool vis[N];
int f[N],S[N];
void getroot(int x,int fa){
size[x]=;maxn[x]=;
for(int i=head[x];i;i=ed[i].next){
int v=ed[i].v;
if(v==fa||!vis[v])continue;
getroot(v,x);
size[x]+=size[v];
maxn[x]=max(maxn[x],size[v]);
}
maxn[x]=max(maxn[x],sum-size[x]);
if(maxn[x]<maxn[root])root=x;
}
void init(int x,int fa){
f[x]=fa;vis[x]=;
int all=sum;
for(int i=head[x];i;i=ed[i].next){
int v=ed[i].v;
if(!vis[v])continue;
sum=size[v]<size[x]?size[v]:all-size[x];
root=;
getroot(v,);
init(root,x);
}
}
int T,tim[N];
void dfs1(int x,int fa,int s){
vis[x]=;sum++;S[x]=;tim[x]=T;
dfs(Treap::root[x]);Treap::root[x]=Treap::null;
dfs(Treap::root1[x]);Treap::root1[x]=Treap::null;
for(int i=head[x];i;i=ed[i].next){
int v=ed[i].v;
if(v==fa||S[v]>s)continue;
dfs1(v,x,s);
}
}
void dfs2(int x,int fa,int en){
int now=x;
while(now!=en){
S[now]++;
Treap::insert(Treap::root[now],dis(x,now)-r[x]);
if(f[now])Treap::insert(Treap::root1[now],dis(x,f[now])-r[x]);
now=f[now];
}
for(int i=head[x];i;i=ed[i].next){
int v=ed[i].v;
if(v==fa||tim[v]!=T)continue;
dfs2(v,x,en);
}
}
void rebuild(int x){
int fa=f[x];T++;sum=;
dfs1(x,,S[x]);root=;
getroot(x,);
init(root,fa);
dfs2(x,,fa);
}
int query(int x){
int now=x;
int cnt=getrank(Treap::root[now],r[x]+);
while(f[now]){
cnt+=Treap::getrank(Treap::root[f[now]],r[x]-dis(x,f[now])+)
-Treap::getrank(Treap::root1[now],r[x]-dis(x,f[now])+);
now=f[now];
}
return cnt-;
}
void insert(int x){
if(x>)add(x,f[x]),add(f[x],x);
fa[x][]=f[x];
dep[x]=dep[fa[x][]]+;
val[x]=val[f[x]]+w[x];
for(int i=;(<<i)<=dep[x];i++)
fa[x][i]=fa[fa[x][i-]][i-];
S[x]++;
int now=x,ret=;
while(f[now]){
Treap::insert(Treap::root[now],dis(x,now)-r[x]);
Treap::insert(Treap::root1[now],dis(x,f[now])-r[x]);
S[f[now]]++;
if(S[now]>S[f[now]]*0.88)ret=f[now];
now=f[now];
}Treap::insert(Treap::root[now],dis(x,now)-r[x]);
if(ret)rebuild(ret);
ans+=query(x);
}
int main(){
n=get();n=get();maxn[]=N;
Treap::init();
for(int i=;i<=n;i++){
f[i]=get();w[i]=get();r[i]=get();
f[i]=f[i]^(ans%);
insert(i);
printf("%lld\n",ans);
}
return ;
}

bzoj3435 [Wc2014]紫荆花之恋的更多相关文章

  1. BZOJ3435[Wc2014]紫荆花之恋——动态点分治(替罪羊式点分树套替罪羊树)

    题目描述 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来.仔细看看的话,这个大树实际上是一个带权树.每 ...

  2. BZOJ3435: [Wc2014]紫荆花之恋(替罪羊树,Treap)

    Description 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来.仔细看看的话,这个大树实际上是 ...

  3. bzoj3435 [Wc2014]紫荆花之恋(动态点分治+替罪羊树)

    传送门(权限) 传送门(非权限) 题解 我终终终终终终于做出来啦!!! 作为一个没有学过替罪羊树的蒟蒻现场学了一下替罪羊树,作为一个平衡树都写数组版本的看着大佬的指针题解无语只能硬去理解然后照着抄了一 ...

  4. 【BZOJ3435】[Wc2014]紫荆花之恋 替罪点分树+SBT

    [BZOJ3435][Wc2014]紫荆花之恋 Description 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从 ...

  5. bzoj 3435: [Wc2014]紫荆花之恋 替罪羊树维护点分治 && AC400

    3435: [Wc2014]紫荆花之恋 Time Limit: 240 Sec  Memory Limit: 512 MBSubmit: 159  Solved: 40[Submit][Status] ...

  6. BZOJ 3435: [Wc2014]紫荆花之恋

    二次联通门 : BZOJ 3435: [Wc2014]紫荆花之恋 二次联通门 : luogu P3920 [WC2014]紫荆花之恋 /* luogu P3920 [WC2014]紫荆花之恋 怀疑人生 ...

  7. luogu P3920 [WC2014]紫荆花之恋

    LINK:紫荆花之恋 每次动态加入一个节点 统计 有多少个节点和当前节点的距离小于他们的权值和. 显然我们不能n^2暴力. 考虑一个简化版的问题 树已经给出 每次求某个节点和其他节点的贡献. 不难想到 ...

  8. BZOJ3435 & 洛谷3920 & UOJ55:[WC2014]紫荆花之恋

    https://www.lydsy.com/JudgeOnline/problem.php?id=3435 https://www.luogu.org/problemnew/show/P3920 ht ...

  9. 【bzoj3435】[Wc2014]紫荆花之恋 替罪点分树套SBT

    题目描述 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来.仔细看看的话,这个大树实际上是一个带权树.每 ...

随机推荐

  1. java finalize方法总结、GC执行finalize的过程

    注:本文的目的并不是鼓励使用finalize方法,而是大致理清其作用.问题以及GC执行finalize的过程. 1. finalize的作用 finalize()是Object的protected方法 ...

  2. SNMP相关的RFC建议和链接

    1. SNMP Books or Articleshttp://www.faqs.org/faqs/snmp-faq/part1/http://www.faqs.org/faqs/snmp-faq/p ...

  3. Jquery测试题

    一.Jquery测试题 下面哪种不是jquery的选择器?(单选) A.基本选择器 B.后代选择器 C.类选择器 D.进一步选择器 考点:jquery的选择器 (C) 当DOM加载完成后要执行的函数, ...

  4. jquery中利用队列依次执行动画

    如果有5个隐藏的div,要让它们依次显示,通常的做法是要一个一个嵌套在回调函数里面,这样导致代码看起来非常不直观. $("#div1").slideDown(1000,functi ...

  5. Testng基本问题

    Testng testng.xml suite属性说明: suite verbose="4" 命令行信息打印等级 1~5 parallel 是否多线程并发运行测试:可选值(fals ...

  6. Oracle100w数据大表割接

    [现网问题] 最近在给咪咕做视频后台管理,移动那边希望页面上,码流字段可以支持1位小数,如8.0.自己查看数据库,发现码流字段是Number整型,也就是要换类型,打算直接换成varchar2.因为自己 ...

  7. python 要掌握面向对象,你得会做这些题吗?

    1,面向对象三大特性,各有什么用处,说说你的理解. 继承:解决代码重用问题 多态:多态性,可以在不考虑对象类型的情况下而直接使用对象 封装:明确的区分内外,控制外部对隐藏属性的操作行为,隔离复杂度 2 ...

  8. CSS 静态进度条效果

    今天学习到了实现一个静态进度条的方法,固写一篇笔记稳固一下自己的知识. 最终的效果如下,进度条放在一个框里,水平宽自适应. 现在就开始,首先写一个进度条先. .progress-bar{ /* 进度条 ...

  9. shell脚本头,#!/bin/sh与#!/bin/bash的区别.

    因为今天写了个小脚本,死活不成功,总是报文件或者目录不存在,问了一下我们马同学的正常写法,发现只有脚本头的区别,也就是今天本文要讲的#!/bin/sh与#!/bin/bash. 本文参考:https: ...

  10. 团队项目第二阶段个人进展——Day10

    一.昨天工作总结 冲刺第十天,做程序的测试,并修复一些小的bug 二.遇到的问题 无 三.今日工作规划 继续对程序进行测试优化