题目链接: PowerOj1179
1179: 我要10个G
Time Limit: 8500 MS Memory Limit: 2097152 KBTotal Submit: 7 Accepted: 5 Page View: 21
Submit Status Discuss
Description
大黄对于以太网的速度要求不是一般的高,要求达到10Gbps的速度。于是上决╇ф把实验室内的网络设备全部更换成了万兆的。由于资金紧缺,上决╇ф不得不从深水宝购买这些万兆设备。后果可想而知,这些设备的的稳定性不堪入目,经常罢工。然而大黄和梁晨这小两口经常换位置。大黄想知道,每次换位置后,她和梁晨之间的网络是否通畅。
Input
输入第一行两个正整数
n,qn,q(
1≤n,q≤1051≤n,q≤105),分别代表实验室内网络设备的个数和日志条数。 接下来
n−1n−1行,每行有两个正整数
u,vu,v(
1≤u,v≤n1≤u,v≤n)。表示编号为
uu的设备和编号为
vv的设备之间通过一条高贵的七类屏蔽线连接。 接下来
qq行,第一个数
optopt(
1≤opt≤31≤opt≤3)代表日志类别。 当
opt=1opt=1时,后面将会有两个正整数
u,vu,v(
1≤u,v≤n1≤u,v≤n)。表示现在大黄的电脑连接在编号为
uu设备上,梁晨的电脑连接连接在编号为
vv的设备上。询问大黄和梁晨之间的网络是否通畅。 当
opt=2opt=2时,后面将会有一个正整数
uu(
1≤u≤n1≤u≤n)。表示编号为
uu的设备被上决╇ф修好了。 当
opt=3opt=3时,后面将会有一个正整数
uu(
1≤u≤n1≤u≤n)。表示编号为
uu的设备损坏了。 输入保证任意两台设备都是直接或间接地通过网线连通的。初始的时候,所有的网络设备都是正常工作的。并且保证不会维修一个好的设备,也不会出现已损坏的设备再次损坏的情况。
Output
对于每一次询问日志,如果大黄和梁晨之间的网络通畅,没有损坏的设备,输出“YES”,否则“NO”
7 82 13 24 35 46 17 11 7 63 21 3 73 41 6 23 11 5 21 3 5
YESNONONONO
题目大意:
给你一颗n个节点的树和q次查询,查询为
1 u v 问u->v是否联通
2 u 将u节点修复好
3 u u节点损坏
初始都是好的,,保证输入合法不存在修复好的节点,损坏坏的节点
题目思路:
对于树上节点区间的查询和节点的修改我们很好想到的是树链剖分,对于初始时所有节点的值为1,如果查询u->v
是否联通则u->v的距离为他们之间经过点的个数,如果不等则不联通,对于树链求点数可以先求出lca来
再根据深度算出来
AC代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 2e5+100;
/** 邻接表部分 */
struct st
{
int v,nex;
}edge[maxn<<1];
int head[maxn],e;
void add(int u,int v)
{
edge[e].v = v,edge[e].nex = head[u],head[u]=e++;
}
/** 树链剖分部分 */
int fa[maxn],dep[maxn],siz[maxn],top[maxn],son[maxn],pos[maxn],rak[maxn],val[maxn];;
int tim;
void dfs(int u,int pr,int d)
{
siz[u] = 1,dep[u]=d,fa[u] = pr;
for(int i = head[u];~i;i=edge[i].nex)
{
int v = edge[i].v;
if(v==pr)continue;
dfs(v,u,d+1);
siz[u]+=siz[v];
if(son[u]==-1||siz[son[u]]<siz[v])
son[u]=v;
}
}
void create(int u,int tp)
{
top[u] = tp;
pos[u] = ++tim;
rak[pos[u]] = u;
if(son[u]==-1)return ;
create(son[u],tp);
for(int i=head[u];~i;i=edge[i].nex)
{
int v = edge[i].v;
if(v != fa[u]&&v != son[u])create(v,v);
}
}
/** 线段树部分 */
struct nod
{
int l,r;
int sum,c;
}node[maxn<<3];
void pushdown(int rt,int m)
{
node[rt<<1].c+=node[rt].c;
node[rt<<1|1].c+=node[rt].c;
node[rt<<1].sum+=node[rt].c*(m-m/2);
node[rt<<1|1].sum+=node[rt].c*(m/2);
node[rt].c = 0;
}
void pushup(int rt)
{
node[rt].sum = node[rt<<1].sum+node[rt<<1|1].sum;
}
void BuildTree(int l,int r,int rt)
{
node[rt].l = l,node[rt].r = r,node[rt].c =0;
if(l==r)
{
node[rt].sum = val[rak[l]];
return ;
}
int mid = (l+r)>>1;
BuildTree(l,mid,rt<<1);
BuildTree(mid+1,r,rt<<1|1);
pushup(rt);
}
void update(int l,int r,int rt,int w)
{
if(l<=node[rt].l&&r>=node[rt].r)
{
node[rt].sum+=(node[rt].r-node[rt].l+1)*w;
node[rt].c+=w;
return ;
}
if(node[rt].c)pushdown(rt,node[rt].r-node[rt].l+1);
int mid = (node[rt].l+node[rt].r)>>1;
if(l<=mid)update(l,r,rt<<1,w);
if(r>mid)update(l,r,rt<<1|1,w);
pushup(rt);
}
int quary(int L,int R,int l,int r,int rt)
{
if(r<L||l>R)return 0;
if(L<=l&&R>=r)return node[rt].sum;
int mid = (l+r)>>1;
if(node[rt].c)pushdown(rt,r-l+1);
return quary(L,R,l,mid,rt<<1)+quary(L,R,mid+1,r,rt<<1|1);
}
/** 运行部分 */
int n,m,p;
int len;
void change(int x,int y,int w)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
update(pos[top[x]],pos[x],1,w);
x = fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
update(pos[x],pos[y],1,w);
}
int SUM(int x,int y)
{
len = 0; //记录点数
int sum = 0; //记录距离
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
sum+=quary(pos[top[x]],pos[x],1,n,1);
len+=abs(dep[x]-dep[fa[top[x]]]);
x = fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
len+=dep[y]-dep[x]+1;
sum+=quary(pos[x],pos[y],1,n,1);
return sum;
}
void init()
{
tim = e = 0;
memset(head,-1,sizeof(head));
memset(son,-1,sizeof(son));
}
void sove()
{
for(int i=1;i<=n;i++)val[i] = 1;
for(int i=1;i<n;i++)
{
int x,y;scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs(1,1,1);
create(1,1);
BuildTree(1,n,1);
while(p--)
{
int s;
int x,y,w;
scanf("%d",&s);
if(s==1)
{
scanf("%d%d",&x,&y);
int xx = SUM(x,y);
if(xx==len)printf("YES\n");
else printf("NO\n");
}
else if(s==2)
{
scanf("%d",&x);
change(x,x,1);
}
else
{
scanf("%d",&x);
change(x,x,-1);
}
}
}
int main()
{
scanf("%d%d",&n,&p);
init();
sove();
return 0;
}