jzoj6276. 【noip提高组模拟1】树

Input

（注意，这里我们不保证同样的点对<x,y>不会重复出现）

8 3
1 2
1 3
4 8
2 4
2 5
3 6
3 7
2 3
4 8
6 7

11

10分妙啊♂

标程

``````
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

struct qy
{
int bz,sum;
};
struct kk
{
int x,l,r,gg;
};

long long n,m,i,j,k,x,y,ans,t,l1,r1,l2,r2,sum,bz;
long long l[200005],next[200005],last[200005],tot;
long long depth[200005],dfn[200005],size[200005],fa[200005][18];
kk list[800005];
qy tree[800005];

void buildtree(long long x,long long faa)
{
size[x]=1;
dfn[x]=++sum;
for (int i=1;i<=17;i++)
{
fa[x][i]=fa[fa[x][i-1]][i-1];
}
for (long long i=last[x];i>=1;i=next[i])
{
if (l[i]!=faa)
{
depth[l[i]]=depth[x]+1;
fa[l[i]][0]=x;
buildtree(l[i],x);
size[x]+=size[l[i]];
}
}
}

void insert(long long x,long long y)
{
l[++tot]=y;
next[tot]=last[x];
last[x]=tot;
}

void add(long long l1,long long r1,long long l2,long long r2)
{
tot++;
list[tot].l=l2;list[tot].r=r2;
list[tot].x=l1;list[tot].gg=1;
tot++;
list[tot].l=l2;list[tot].r=r2;
list[tot].x=r1+1;list[tot].gg=-1;

tot++;
list[tot].l=l1;list[tot].r=r1;
list[tot].x=l2;list[tot].gg=1;
tot++;
list[tot].l=l1;list[tot].r=r1;
list[tot].x=r2+1;list[tot].gg=-1;
}

int comp(kk a,kk b)
{
return a.x<b.x;
}

int jump(int x,int steps)
{
int y=x;
for (int i=17;i>=0;i--)
{
if (depth[x]-depth[fa[y][i]]<=steps)
{
y=fa[y][i];
}
}
return y;
}

void build(int k,int l,int r)
{
tree[k].sum=r-l+1;
tree[k].bz=0;
if (l!=r)
{
int mid=(l+r)/2;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
}
}

void modify(int k,int l,int r,int x,int y,int z)
{
if ((l<=y)&&(r>=x))
{
if ((l>=x)&&(r<=y))
{
tree[k].bz+=z;
if (tree[k].bz==0)
{
if (l!=r)
tree[k].sum=tree[k*2].sum+tree[k*2+1].sum;
else
tree[k].sum=1;
}
else
tree[k].sum=0;
return;
}
int mid=(l+r)/2;
modify(k*2,l,mid,x,y,z);
modify(k*2+1,mid+1,r,x,y,z);
if (tree[k].bz==0)
tree[k].sum=tree[k*2].sum+tree[k*2+1].sum;
else
tree[k].sum=0;
}
}

int main()
{
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
scanf("%lld%lld",&n,&m);
for (i=1;i<=n-1;i++)
{
scanf("%lld%lld",&x,&y);
insert(x,y);
insert(y,x);
}
depth[1]=1;
buildtree(1,0);
tot=0;
for (i=1;i<=m;i++)
{
scanf("%lld%lld",&x,&y);
if (depth[x]<depth[y]) swap(x,y);
if ((depth[x]==depth[y])||(jump(x,depth[x]-depth[y])!=y))
{
l1=dfn[x];
r1=dfn[x]+size[x]-1;
l2=dfn[y];
r2=dfn[y]+size[y]-1;
}
else
{
t=jump(x,depth[x]-depth[y]-1);
l1=dfn[x];
r1=dfn[x]+size[x]-1;
l2=1;
r2=dfn[t]-1;
l2=dfn[t]+size[t];
r2=n;
}
}
sort(list+1,list+1+tot,comp);
build(1,1,n);
bz=0;
for (i=1;i<=n;i++)
{
while ((bz+1<=tot)&&(list[bz+1].x<=i))
{
bz++;
modify(1,1,n,list[bz].l,list[bz].r,list[bz].gg);
}
ans=ans+tree[1].sum;
}
printf("%lld",(ans-n)/2);
}``````

jzoj6276. 【noip提高组模拟1】树

(0)
(0)