题解:

这一道题目和模板有不同的地方就是在于可以修改只有一条边和i相邻

于是我们还要记录与这个点相邻的点有没有改变

代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
const int N=;
using namespace std;
int fi[N],zz[N],ne[N],deep[N],fa[N],size[N],son[N],top[N];
int x,y,opt,pos[N],q[N],cnt,h[N],tot,n,m,T;
struct data
{
int w,b,delta,rev;
}tr[N*];
void add(int x,int y)
{
ne[++tot]=fi[x];
fi[x]=tot;
zz[tot]=y;
}
void dfs(int x,int f)
{
size[x]=; son[x]=;
deep[x]=deep[f]+;
for (int i=fi[x];i;i=ne[i])
{
if (zz[i]==f) continue;
fa[zz[i]]=x;
dfs(zz[i],x);
size[x]+=size[zz[i]];
if (size[zz[i]]>size[son[x]]) son[x]=zz[i];
}
}
void dfs1(int x,int y)
{
pos[x]=++cnt;q[cnt]=x;top[x]=y;
if (!son[x])return;
dfs1(son[x],y);
for (int i=fi[x];i;i=ne[i])
if (zz[i]!=son[x]&&zz[i]!=fa[x])
dfs1(zz[i],zz[i]);
}
void update(data &now,data l,data r)
{
now.w=l.w+r.w;
now.b=l.b+r.b;
}
void clear(int now)
{
tr[now].b=tr[now].w=tr[now].rev=tr[now].delta=;
}
void build(int now,int l,int r)
{
clear(now);
if (l==r)
{
tr[now].b=;
if (l!=) tr[now].w=;
return;
}
int mid=(l+r)/;
build(now<<,l,mid);
build(now<<|,mid+,r);
update(tr[now],tr[now<<],tr[now<<|]);
}
void change(int now)
{
swap(tr[now].w,tr[now].b);
tr[now].delta^=;
}
void pushdown(int now)
{
if (tr[now].delta)
{
change(now<<);
change(now<<|);
tr[now].delta=;
}
if (tr[now].rev)
{
tr[now<<].rev^=; tr[now<<|].rev^=;
tr[now].rev=;
}
}
data query(int now,int l,int r,int ll,int rr)
{
if (ll<=l&&r<=rr) return tr[now];
pushdown(now);
int mid=(l+r)/;data ans;int pd=;
if (ll<=mid) ans=query(now<<,l,mid,ll,rr),pd=;
if (rr>mid)
{
if (pd) update(ans,ans,query(now<<|,mid+,r,ll,rr));
else ans=query(now<<|,mid+,r,ll,rr);
}
return ans;
}
void qjchange(int now,int l,int r,int ll,int rr)
{
if (ll<=l&&r<=rr)
{
change(now);
return;
}
int mid=(l+r)/;
pushdown(now);
if (ll<=mid) qjchange(now<<,l,mid,ll,rr);
if (rr>mid) qjchange(now<<|,mid+,r,ll,rr);
update(tr[now],tr[now<<],tr[now<<|]);
}
void reverse(int now,int l,int r,int ll,int rr)
{
if (ll<=l&&r<=rr)
{
tr[now].rev^=;
return;
}
pushdown(now);
int mid=(l+r)/;
if (ll<=mid) reverse(now<<,l,mid,ll,rr);
if (rr>mid) reverse(now<<|,mid+,r,ll,rr);
update(tr[now],tr[now<<],tr[now<<|]);
}
void solve(int x,int y)
{
while (top[x]!=top[y])
{
if (deep[top[x]]<deep[top[y]]) swap(x,y);
qjchange(,,n,pos[top[x]],pos[x]);
x=fa[top[x]];
}
if (deep[x]>deep[y]) swap(x,y);
if (x==y) return;
qjchange(,,n,pos[x]+,pos[y]);
}
void paint(int x,int y)
{
bool pd=false;
int t=;
while (top[x]!=top[y])
{
if (deep[top[x]]<deep[top[y]]) swap(x,y);
reverse(,,n,pos[top[x]],pos[x]);
if (son[x]) qjchange(,,n,pos[son[x]],pos[son[x]]);
qjchange(,,n,pos[top[x]],pos[top[x]]);
t=top[x]; x=fa[top[x]]; h[x]=t;
}
if (deep[x]>deep[y]) swap(x,y);
reverse(,,n,pos[x],pos[y]);
qjchange(,,n,pos[x],pos[x]);
if (son[y]) qjchange(,,n,pos[son[y]],pos[son[y]]);
}
int find(int now,int l,int r,int x)
{
if (x==) return ;
if (l==r) return tr[now].rev;
int mid=(l+r)/;
pushdown(now);
if (x<=mid) return find(now<<,l,mid,x);
else return find(now<<|,mid+,r,x);
}
int calc(int x,int y)
{
int ans=;
while (top[x]!=top[y])
{
if (deep[top[x]]<deep[top[y]]) swap(x,y);
data t=query(,,n,pos[top[x]],pos[x]);
data t1=query(,,n,pos[top[x]],pos[top[x]]);
int k=find(,,n,pos[fa[top[x]]]);
if (t1.b==&&k) t.b--;
if (t1.w==&&k) t.b++;
ans+=t.b;
x=fa[top[x]];
}
if (deep[x]>deep[y]) swap(x,y);
if (x==y) return ans;
data t=query(,,n,pos[x]+,pos[y]);
return ans+t.b;
}
int main()
{
scanf("%d",&T);
while (T--)
{
tot=cnt=;
memset(fi,,sizeof fi);
scanf("%d",&n);
for (int i=;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
dfs(,);dfs1(,);build(,,n);
scanf("%d",&m);
while (m--)
{
scanf("%d%d%d",&opt,&x,&y);
if (opt==) solve(x,y);
if (opt==) paint(x,y);
if (opt==) printf("%d\n",calc(x,y));
}
}
return ;
}

bzoj3862的更多相关文章

  1. BZOJ3862 Little Devil I 树链剖分

    原文链接http://www.cnblogs.com/zhouzhendong/p/8081514.html 题目传送门 - BZOJ3862 题意概括 一棵树,n个点,边权为黑或者白,支持3重操作: ...

随机推荐

  1. linux IO多路复用POLL机制深入分析

    POLL机制的作用这里就不进行介绍,根据linux man手册,解释为在一个文件描述符上等待某个事件.按照抽象一点的理解,当某个事件被触发(条件被满足),文件描述符变为有状态,那么用户空间可以根据此进 ...

  2. receive.denyCurrentBranch 推送错误解决

    场景: 1.搭建Ok了一git服务器 2.本机上的现有源码,现在想纳入git源码管理 操作: 1.服务器上创建了工程仓库 git init 2. 客户端使用tortoisegit添加并提交要纳入源码管 ...

  3. day11(jsp入门&Cookie&HttpSession&一次性图片校验码)

    day11 JSP入门   1 JSP概述 1.1 什么是JSP JSP(Java Server Pages)是JavaWeb服务器端的动态资源.它与html页面的作用是相同的,显示数据和获取数据. ...

  4. sql server中带有output的DML

    OUTPUT是SQL SERVER2005的新特性.可以从数据修改语句中返回输出.可以看作是"返回结果的DML".INSERT,DELETE,UPDATE均支持OUTPUT子句.在 ...

  5. Zabbix设置自定义监控

    [zabbix]自定义监控项key值   说明: zabbix自带的默认模版里包括了很多监控项,有时候为了满足业务需求,需要根据自己的监控项目自定义监控项,这里介绍一种自定义监控项的方式. 1,首先编 ...

  6. python 利用爬虫获取页面上下拉框里的所有国家

    前段时间,领导说列一下某页面上的所有国家信息,话说这个国家下拉框里的国家有两三百个,是第三方模块导入的,手动从页面拷贝,不切实际,于是想着用爬虫去获取这个国家信息,并保存到文件里. 下面是具体的代码, ...

  7. 15信号sigaction

    信号处理 信号值小于 SIGRTMIN 的信号 (1~31) 都是不可靠信号 某些unix版本中,调用信号函数处理后会自动恢复默认信号处理,所以在信号处理函数中还需要继续调用signal函数设置信号处 ...

  8. 2016 CCPC 长春 Solution

    A - Hanzo vs. Genji 留坑. B - Fraction 水. #include <bits/stdc++.h> using namespace std; inline i ...

  9. Arthur and Brackets

    n<605设计出n对夸号  给出n个条件每个条件为[l,r] 表示第i对夸号右夸号离左夸号的距离,然后夸号的右夸号出现的顺序必须按照给的顺序 出现, 那么如果存在就输出否则输出impossilb ...

  10. Java的Servlet、Filter、Interceptor、Listener

    写在前面: 使用Spring-Boot时,嵌入式Servlet容器可以通过扫描注解(@ServletComponentScan)的方式注册Servlet.Filter和Servlet规范的所有监听器( ...