bzoj3435 [Wc2014]紫荆花之恋
如果这棵树不变的话,就是一个裸的点分树套平衡树,式子也很好推$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]紫荆花之恋的更多相关文章
- BZOJ3435[Wc2014]紫荆花之恋——动态点分治(替罪羊式点分树套替罪羊树)
题目描述 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来.仔细看看的话,这个大树实际上是一个带权树.每 ...
- BZOJ3435: [Wc2014]紫荆花之恋(替罪羊树,Treap)
Description 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来.仔细看看的话,这个大树实际上是 ...
- bzoj3435 [Wc2014]紫荆花之恋(动态点分治+替罪羊树)
传送门(权限) 传送门(非权限) 题解 我终终终终终终于做出来啦!!! 作为一个没有学过替罪羊树的蒟蒻现场学了一下替罪羊树,作为一个平衡树都写数组版本的看着大佬的指针题解无语只能硬去理解然后照着抄了一 ...
- 【BZOJ3435】[Wc2014]紫荆花之恋 替罪点分树+SBT
[BZOJ3435][Wc2014]紫荆花之恋 Description 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从 ...
- bzoj 3435: [Wc2014]紫荆花之恋 替罪羊树维护点分治 && AC400
3435: [Wc2014]紫荆花之恋 Time Limit: 240 Sec Memory Limit: 512 MBSubmit: 159 Solved: 40[Submit][Status] ...
- BZOJ 3435: [Wc2014]紫荆花之恋
二次联通门 : BZOJ 3435: [Wc2014]紫荆花之恋 二次联通门 : luogu P3920 [WC2014]紫荆花之恋 /* luogu P3920 [WC2014]紫荆花之恋 怀疑人生 ...
- luogu P3920 [WC2014]紫荆花之恋
LINK:紫荆花之恋 每次动态加入一个节点 统计 有多少个节点和当前节点的距离小于他们的权值和. 显然我们不能n^2暴力. 考虑一个简化版的问题 树已经给出 每次求某个节点和其他节点的贡献. 不难想到 ...
- BZOJ3435 & 洛谷3920 & UOJ55:[WC2014]紫荆花之恋
https://www.lydsy.com/JudgeOnline/problem.php?id=3435 https://www.luogu.org/problemnew/show/P3920 ht ...
- 【bzoj3435】[Wc2014]紫荆花之恋 替罪点分树套SBT
题目描述 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来.仔细看看的话,这个大树实际上是一个带权树.每 ...
随机推荐
- jQuery如何停止元素的animate动画,还有怎样判断是否处于动画状态
jquery的animation会自动进入队列,就出现了一个问题,这些动画会一一执行完成,而我们实际的本意是当鼠标移开的时候动画即终止. 停止元素的动画方法:stop()语法结构:stop([clea ...
- java并发之可见性与原子性:Syncronized和volatile
转载:http://blog.csdn.net/guyuealian/article/details/52525724 在说明Java多线程内存可见性之前,先来简单了解一下Java内存模型. ...
- python3.6 安装win32api时候找不到regitry的问题
首先下载 https://sourceforge.net/projects/pywin32/files/pywin32/ 找到对应的即可 我需要的是这个 打开之后会提示3.6未注册 在任意位置新建一个 ...
- C#文件和字节流的转换方法
1.读取文件,并转换为字节流 FileStream fs = new FileStream(filename,FileMode.Open,FileAccess.Read); byte[] infbyt ...
- Android之淘宝商品列表长按遮罩效果
先来看看淘宝.唯品会长按商品的效果,以及简单Demo的效果: 首先分析一下场景: 长按条目时,弹出遮罩的效果遮挡在原来的条目布局上: 页面滑动或点击其他的条目,上一个正在遮罩的条目遮罩消 ...
- Unity3d Mecanim动画系统Animator学习笔记
1. unity3d Mecanim学习 Unity3d新版动画系统网上的介绍很多,但多是流水笔记,外人很难看明白,后来我 终于找到介绍的比较明白的两个作者,特别感谢.一个是58开发网的乐天老师,课 ...
- Spring结合log4j(slf4j)
maven依赖 <!-- slf4j (级联:log4j/slf4j-api) --> <dependency> <groupId> ...
- Surface pro 4 使用心得
今天谈谈这几个月Surface pro 4的使用心得.这篇后面有点跑题,行文也比较随意,就当闲笔了. 设备简述 使用体验 优点 不足 优雅使用 系统界面 应用 系统应用 工具应用 生产工具 其他应用 ...
- 修改ZendStudio新建php文件时的模板
zendstudio默认的模板不适用,可以自己到Window -- preferences -- php -- code style -- code templates -- code -- samp ...
- SSH X11 MAC
1. X11 for Mac 2. Ubuntu下通过SSH转发X窗口需要具备的条件 原文:http://unix.stackexchange.com/questions/12755/how- ...