题解:

这一道题目和模板有不同的地方就是在于可以修改只有一条边和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. leetcode之Maximal Square

    Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and ret ...

  2. Python开发【模块】:M2Crypto RSA加密、解密

    M2Crypto 模块 快速安装: # 环境centos7.0,提前装好openssl(自行百度安装),windows装不上,暂不考虑了 [root@localhost ~]# pip install ...

  3. Python开发【项目】:生产环境下实时统计网站访问日志信息

    日志实时分析系统 生产环境下有需求:要每搁五分钟统计下这段时间内的网站访问量.UV.独立IP等信息,用直观的数据表格表现出来 环境描述: 网站为Nginx服务,系统每日凌晨会对日志进行分割,拷贝到其他 ...

  4. python并发

    并发方式 线程(Thread) 多线程几乎是每一个程序猿在使用每一种语言时都会首先想到用于解决并发的工具(JS程序员请回避),使用多线程可以有效的利用CPU资源(Python例外).然而多线程所带来的 ...

  5. Flask wtform组件

    Wtforms简介 WTForms是一个支持多个web框架的form组件 主要能够帮助我们生成html标签 对数据进行验证 安装 pip install wtforms Wtforms的使用 这里借助 ...

  6. 数据挖掘-逻辑Logistic回归

    逻辑回归的基本过程:a建立回归或者分类模型--->b 建立代价函数 ---> c 优化方法迭代求出最优的模型参数  --->d 验证求解模型的好坏. 1.逻辑回归模型: 逻辑回归(L ...

  7. webdriver js点击无法点击的元素

    原文地址https://blog.csdn.net/galen2016/article/details/56847545 [WebDriver]调用JavaScript 一.WebDriver 提供了 ...

  8. testng日志 TestListenerAdapter

    TestListenerAdapter,空方法实现 ITestListener   创建自定义日志记录类 创建另一个新的类名为 CustomListener.java 在 C:\ > TestN ...

  9. A题:Common Substrings(KMP应用)

    原题链接 注意:2号和3号get_next()函数中next[i]赋值时的区别,一个是0,一个是1,且不能互换 #include<cstdio> #include<cstring&g ...

  10. VS2010/MFC编程入门之十八(对话框:字体对话框)

    鸡啄米在上一节为大家讲解了文件对话框的使用,本节则主要介绍字体对话框如何应用. 字体对话框的作用是用来选择字体.我们也经常能够见到.MFC使用CFontDialog类封装了字体对话框的所有操作.字体对 ...