您的位置:首页 > 其它

AC日记——[LNOI2014]LCA bzoj 3626

2017-06-18 18:29 375 查看
3626

思路:

  离线操作+树剖;

代码:

#include <bits/stdc++.h>
using namespace std;
#define maxn 100005
#define maxm maxn<<2
#define ll long long
#define mod 201314
struct QueryType {
int now,id,pos,z;
bool operator<(const QueryType pos)const
{
return now<pos.now;
}
};
struct QueryType qu[maxn<<1];
int n,m,f[maxn],top[maxn],lar[maxn],size[maxn],id[maxn],deep[maxn];
int L[maxm],R[maxm],mid[maxm],head[maxn],E[maxn],V[maxn],cnt;
ll dis[maxm],ans[maxn],flag[maxm],Qes;
inline void in(int &now)
{
char Cget=getchar();now=0;
while(Cget>'9'||Cget<'0')Cget=getchar();
while(Cget>='0'&&Cget<='9')
{
now=now*10+Cget-'0';
Cget=getchar();
}
}
void dfs1(int now)
{
size[now]=1,deep[now]=deep[f[now]]+1;
for(int i=head[now];i;i=E[i])
{
dfs1(V[i]),size[now]+=size[V[i]];
if(size[lar[now]]<size[V[i]]) lar[now]=V[i];
}
}
void dfs2(int now,int chain)
{
top[now]=chain,id[now]=++cnt;
if(lar[now]) dfs2(lar[now],chain);
for(int i=head[now];i;i=E[i])
{
if(V[i]==lar[now]) continue;
dfs2(V[i],V[i]);
}
}
void build(int now,int l,int r)
{
L[now]=l,R[now]=r;if(l==r) return;mid[now]=l+r>>1;
build(now<<1,l,mid[now]),build(now<<1|1,mid[now]+1,r);
}
void downdata(int now)
{
flag[now<<1]+=flag[now],flag[now<<1|1]+=flag[now];
dis[now<<1]+=flag[now]*(R[now<<1]-L[now<<1]+1);
dis[now<<1|1]+=flag[now]*(R[now<<1|1]-L[now<<1|1]+1);
flag[now]=0;
}
void add(int now,int l,int r)
{
if(L[now]>=l&&R[now]<=r)
{
dis[now]+=R[now]-L[now]+1,flag[now]+=1;
return;
}
if(flag[now]) downdata(now);
if(l<=mid[now]) add(now<<1,l,r);
if(r>mid[now]) add(now<<1|1,l,r);
dis[now]=dis[now<<1]+dis[now<<1|1];
}
void query(int now,int l,int r)
{
if(L[now]>=l&&R[now]<=r)
{
Qes+=dis[now];return;
}
if(flag[now]) downdata(now);
if(l<=mid[now]) query(now<<1,l,r);
if(r>mid[now]) query(now<<1|1,l,r);
}
void add(int x,int y)
{
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]]) add(1,id[top[y]],id[y]),y=f[top[y]];
else add(1,id[top[x]],id[x]),x=f[top[x]];
}
if(deep[x]>deep[y]) swap(x,y);add(1,id[x],id[y]);
}
ll query(int x,int y)
{
ll res=0;
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]])
{
Qes=0,query(1,id[top[y]],id[y]);
res+=Qes,y=f[top[y]];
}
else
{
Qes=0,query(1,id[top[x]],id[x]);
res+=Qes,x=f[top[x]];
}
}
if(deep[x]>deep[y]) swap(x,y);
Qes=0,query(1,id[x],id[y]);
return res+Qes;
}
int main()
{
freopen("data.txt","r",stdin);
in(n),in(m);int u,v,w;
for(int i=2;i<=n;i++)
{
in(u),u++,f[i]=u;
E[++cnt]=head[u],V[cnt]=i,head[u]=cnt;
}
cnt=0,dfs1(1),dfs2(1,1),build(1,1,n),cnt=0;
for(int i=1;i<=m;i++)
{
in(u),in(v),in(w),w++;
qu[++cnt].now=u,qu[cnt].id=i,qu[cnt].pos=-1,qu[cnt].z=w;
qu[++cnt].now=v,qu[cnt].id=i,qu[cnt].pos=1,qu[cnt].now++,qu[cnt].z=w;
}
sort(qu+1,qu+cnt+1);int tot=0;
for(int i=1;i<=cnt;i++)
{
if(qu[i].now==0) continue;
while(tot<qu[i].now) add(++tot,1);
ans[qu[i].id]+=query(qu[i].z,1)*qu[i].pos;
}
for(int i=1;i<=m;i++) printf("%lld\n",ans[i]%mod);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: