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重操作: ...
随机推荐
- Delphi下使用指针的简单总结(指针的赋值,数组和指针的转换,函数指针的使用)
由于最近公司太忙,好久没有更新我的BLOG了.原来想着写写关于HOOK驱动的文章,可是最后想想好久已经没有做驱动的东西了,怕写出来有错误,于是作罢.开发游戏也有一段时间了,发现使用DELPHI来开发网 ...
- django2.0集成xadmin0.6报错集锦
1.django2.0把from django.core.urlresolvers修改成了django.urls 报错如下: 1 2 3 File "D:\Envs\django-xad ...
- Flex 布局:实例篇
上一篇文章介绍了Flex布局的语法,今天介绍常见布局的Flex写法.你会看到,不管是什么布局,Flex往往都可以几行命令搞定. 我只列出代码,详细的语法解释请查阅<Flex布局教程:语法篇& ...
- Flask系列之源码分析(一)
目录: 涉及知识点 Flask框架原理 简单示例 路由系统原理源码分析 请求流程简单源码分析 响应流程简单源码分析 session简单源码分析 涉及知识点 1.装饰器 闭包思想 def wapper( ...
- [py][lc]python的纸牌知识点
模块collections-collections.namedtuple表示tuple 如表示一个坐标, t = (1,2), 搞不清楚. 如果这样就对了Point(x=1, y=2) from co ...
- lvs原理及各种调度算法详解
LVS原理详解 LVS原理详解 LVS简介 LVS结构与工作原理 一.LVS的结构 二.LVS内核模型 三.LVS的包转发模型 1.NAT模型: 2.DR模型: 3.TUN模型: 四.LVS的调度算法 ...
- Could not load file or assembly 'Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.414.0, ...
使用oracle数据库一个多月依赖这问题一直都得不到解决,最近任务不是很忙了,所以决定把这问题解决掉.写一篇文章做记录. 以上错误主要是net程序oracle数据库使用了Microsoft Enter ...
- 1 :2 Strust2—Demo
=============================================================== Demo基础包:
- C#——文件操作类简单封装
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.IO ...
- mongodb的分片(2)
在上一片博客,详细说明了mongodb的分片搭建的详细过程:分片搭建 在这里会说一些分片的维护与操作! 在集群搭建完,我们使用了sh.status()查看分片之后的数据,如下: #连接的是mongos ...