bzoj3862
题解:
这一道题目和模板有不同的地方就是在于可以修改只有一条边和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的更多相关文章
- BZOJ3862 Little Devil I 树链剖分
原文链接http://www.cnblogs.com/zhouzhendong/p/8081514.html 题目传送门 - BZOJ3862 题意概括 一棵树,n个点,边权为黑或者白,支持3重操作: ...
随机推荐
- Centos 系统Java环境安装
Java安装 安装SUN的JDK: 官网:http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260. ...
- Python开发【Django】:Model操作(二)
Model操作 1.操作汇总: # 增 # # models.Tb1.objects.create(c1='xx', c2='oo') 增加一条数据,可以接受字典类型数据 **kwargs # obj ...
- 【python】BeautifulSoup的应用
from bs4 import BeautifulSoup#下面的一段HTML代码将作为例子被多次用到.这是 爱丽丝梦游仙境的 的一段内容(以后内容中简称为 爱丽丝 的文档): html_doc = ...
- shell 环境变量的知识小结
环境变量的知识小结:·变量名通常要大写.·变量可以在自身的Shell及子Shell中使用.·常用export来定义环境变量.·执行env默认可以显示所有的环境变量名称及对应的值.·输出时用“$变量名” ...
- PHP之设计模式
https://blog.csdn.net/self_realian/article/details/78228733 掌握PHP各类设计模式,具备设计纯面向对象框架和系统能力是非常有必要的.给大家一 ...
- capistranorb
远程服务器自动部署工具 https://capistranorb.com/
- Python的星号(*)和双星号(**)用法
①引言 在Python中,星号除了用于乘法数值运算和幂运算外,还有一种特殊的用法是在变量前加单个星号或两个星号,实现多参数的传人或变量的拆解. ②什么是星号变量 最初,星号变量是用在函数的参数传递上的 ...
- Ubuntu软件包管理器
Ubuntu软件包管理 Ubuntu下对软件管理工具有:apt,dpkg,tasksel,aptitude等,我们常用的就是前三个工具.下面就介绍这三个工具的用法. dpkg 在Linux发展之初,安 ...
- 【转】微信jssdk录音功能开发记录
转自:http://www.cnblogs.com/liujunyang/p/4962423.html#undefined 0.需求描述 在微信浏览器内打开的页面,制作一个按钮,用户按住按钮后开始录音 ...
- web实现负载均衡的几种实现方式
摘要: 负载均衡(Load Balance)是集群技术(Cluster)的一种应用.负载均衡可以将工作任务分摊到多个处理单元,从而提高并发处理能力.目前最常见的负载均衡应用是Web负载均衡.根据实现的 ...