| 记录编号 |
478099 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
| 题目名称 |
2169.[WC 2014] 紫荆花之恋 |
最终得分 |
100 |
| 用户昵称 |
LadyLex |
是否通过 |
通过 |
| 代码语言 |
C++ |
运行时间 |
71.100 s |
| 提交时间 |
2017-12-08 17:15:10 |
内存使用 |
502.12 MiB |
显示代码纯文本
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <vector>
using namespace std;
#define LL long long
#define inf 1000000000
#define N 100010
#define alpha 0.755
int n,e,adj[N],val[N];
struct edge{int zhong,next;}s[N<<1];
inline void add(int qi,int zhong)
{s[++e].zhong=zhong;s[e].next=adj[qi];adj[qi]=e;}
vector<int> to[N];
int f[N][18],bin[25],tp,deep[N],len[N];
inline int LCA(int a,int b)
{
if(deep[a]<deep[b])a^=b,b^=a,a^=b;
int i,cha=deep[a]-deep[b];
for(i=tp;~i;--i)if(cha&bin[i])a=f[a][i];
if(a==b)return a;
for(i=tp;~i;--i)if(f[a][i]!=f[b][i])a=f[a][i],b=f[b][i];
return f[a][0];
}
inline int dis(int a,int b){return len[a]+len[b]-len[LCA(a,b)]*2;}
struct Goat
{
int val,size;Goat *ch[2];
Goat(){}
inline bool bad()
{return ch[0]->size>=size*alpha+5 || ch[1]->size>=size*alpha+5; }
}*tree1[N],*tree2[N],mem[N<<8],*pool[N<<8],*null,*sta[N];
int tot,top;
inline void intn()
{
null=new Goat();
null->ch[0]=null->ch[1]=null,null->val=null->size=0;
for(int i=0;i<(N<<8);++i)pool[i]=mem+i;
tot=(N<<8)-1;
for(int i=0;i<=n;++i)tree1[i]=tree2[i]=null;
}
inline Goat** insert(Goat *&a,int val)
{
if(a==null)
{
a=pool[tot--],a->ch[0]=a->ch[1]=null;
a->val=val,a->size=1;return &null;
}
++a->size;
Goat **o=insert(a->ch[a->val<val],val);
if(a->bad())o=&a;return o;
}
inline int get_rank(Goat *o,int val)
{
if(o==null)return 0;
return (o->val>=val)?get_rank(o->ch[0],val):(get_rank(o->ch[1],val)+o->ch[0]->size+1);
}
inline void Erholung(Goat *o)
{
if(o==null)return;
if(o->ch[0]!=null)Erholung(o->ch[0]);
pool[++tot]=o;
if(o->ch[1]!=null)Erholung(o->ch[1]);
}
inline void travel(Goat *o)
{
if(o==null)return;
if(o->ch[0]!=null)travel(o->ch[0]);
sta[++top]=o;
if(o->ch[1]!=null)travel(o->ch[1]);
}
inline Goat* build(int l,int r)
{
if(l>r)return null;
int mi=l+r>>1;
Goat *o=sta[mi];o->size=r-l+1;
o->ch[0]=build(l,mi-1),o->ch[1]=build(mi+1,r);
return o;
}
inline void rebuild(Goat *&o){top=0,travel(o),o=build(1,top);}
inline void Insert(Goat *&a,int val)
{
Goat **o=insert(a,val);
if(*o!=null)rebuild(*o);
}
int size[N],maxs[N],totsize,root,Vater[N];
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
bool vis[N];
inline void dfs1(int rt,int fa)
{
size[rt]=1,maxs[rt]=0;
for(int i=adj[rt];i;i=s[i].next)
if(!vis[s[i].zhong]&&s[i].zhong!=fa)
dfs1(s[i].zhong,rt),size[rt]+=size[s[i].zhong],
maxs[rt]=max(maxs[rt],size[s[i].zhong]);
maxs[rt]=max(maxs[rt],totsize-size[rt]);
if(maxs[rt]<maxs[root])root=rt;
}
inline void dfs2(int rt,int fa,int Vatti)
{
// printf("ins:%d<-%d\n",rt,Vatti);
Insert(tree1[Vatti],dis(rt,Vatti)-val[rt]);
if(Vater[Vatti])Insert(tree2[Vatti],dis(rt,Vater[Vatti])-val[rt]);
for(int i=adj[rt];i;i=s[i].next)
if(s[i].zhong!=fa&&!vis[s[i].zhong])
dfs2(s[i].zhong,rt,Vatti);
}
inline void dfs3(int rt,int fa)
{
Vater[rt]=fa,vis[rt]=1;
int siz=totsize;
// printf("%d %d\n",rt,tree1[rt]->size);
dfs2(rt,0,rt);
// printf("%d %d\n",rt,tree1[rt]->size);
for(int i=adj[rt];i;i=s[i].next)
if(!vis[s[i].zhong])
{
if(size[s[i].zhong]>size[rt])totsize=siz-size[rt];
else totsize=size[s[i].zhong];
root=0,dfs1(s[i].zhong,rt),
to[rt].push_back(root),dfs3(root,rt);
}
}
inline void recover(int x)
{
++totsize,vis[x]=0,
Erholung(tree1[x]),Erholung(tree2[x]),
tree1[x]=tree2[x]=null;
for(int i=0,k=to[x].size();i<k;++i)
recover(to[x][i]);
to[x].clear();
}
inline void rebuild(int x)
{
// printf("re:%d\n",x);
totsize=0,recover(x),root=0,dfs1(x,0);
if(Vater[x])
for(int i=0,j=to[Vater[x]].size();i<j;++i)
if(to[Vater[x]][i]==x)to[Vater[x]][i]=root;
// printf("size=%d root=%d Vater=%d\n",totsize,root,Vater[x]);
dfs3(root,Vater[x]);
}
LL ans=0;
inline int insert(int x)
{
int rt,ds,ret=0;
for(rt=x;Vater[rt];rt=Vater[rt])
ds=val[x]-dis(x,Vater[rt])+1,ans+=get_rank(tree1[Vater[rt]],ds)-get_rank(tree2[rt],ds);
for(rt=x;rt;rt=Vater[rt])
{
Insert(tree1[rt],dis(x,rt)-val[x]);
if(Vater[rt])Insert(tree2[rt],dis(x,Vater[rt])-val[x]);
}
for(rt=x;Vater[rt];rt=Vater[rt])
if(tree1[rt]->size>=tree1[Vater[rt]]->size*alpha+5)ret=Vater[rt];//*****
return ret;
}
char B[1<<15],*S=B,*T=B;
#define getc (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?0:*S++)
inline int read()
{
int x=0;register char c=getc;
while(c<'0'||c>'9')c=getc;
while(c>='0'&&c<='9')x=10*x+(c^48),c=getc;
return x;
}
int main()
{
// freopen("Ark.in","r",stdin);
freopen("flowera.in","r",stdin);
freopen("flowera.out","w",stdout);
n=read(),n=read();
register int i,j,x,b;
for(bin[0]=i=1;i<=20;++i)bin[i]=bin[i-1]<<1;
while(bin[tp+1]<=n)++tp;
maxs[0]=inf,root=0,intn();
for(i=1;i<=n;++i)
{
Vater[i]=f[i][0]=read()^(ans%inf),b=read(),val[i]=read();
// printf("%d %d\n",i,Vater[i]);
deep[i]=deep[f[i][0]]+1,len[i]=len[f[i][0]]+b;vis[i]=1;
if(Vater[i])to[Vater[i]].push_back(i),add(f[i][0],i),add(i,f[i][0]);
for(int j=1;bin[j]+1<=deep[i];++j)f[i][j]=f[f[i][j-1]][j-1];
x=insert(i);if(x)rebuild(x);
printf("%lld\n",ans);
}
}