hdu 4897 Little Devil I
传送阵:http://acm.hdu.edu.cn/showproblem.php?pid=4897
题目大意:一棵树,三个操作:1、将某条链取反,2、将与某条链相邻的边取反,3、查询某条链上为1的边数
树链剖分直接上
某条边是否被修改取决于这条边以及这条边的两个端点
对于第一个操作相当于修改边,第二个操作相当于修改点
对于修改边:将标记下放给儿子结点,直接修改即可,修改点也是直接修改,不过要另设一个标记记录
查询时将所有区间合并即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#define maxn 100010
using namespace std;
inline int read(){
int s=;char ch=getchar();
for(;ch<''||ch>'';ch=getchar());
for(;ch>=''&&ch<='';ch=getchar())s=s*+ch-'';
return s;
}
int fa[maxn][],dep[maxn],f[maxn];
int to[maxn<<],Next[maxn<<],tot,h[maxn];
int pos[maxn],sz,size[maxn];
struct node{
int lb,ld,rd,w,s,md,mb;
void clear(){
lb=ld=rd=w=s=mb=md=;
}
friend node operator + (node a,node b){
node ans;
ans.s=a.s+b.s+;
ans.w=a.w+b.w+(a.rd^b.lb^b.ld);
ans.ld=a.ld;
ans.lb=a.lb;
ans.rd=b.rd;
return ans;
}
}t[maxn<<];
int n,q;
void mem(){
tot=;sz=;
memset(h,,sizeof(h));
memset(fa,,sizeof(fa));
memset(dep,,sizeof(dep));
memset(f,,sizeof(f));
memset(pos,,sizeof(pos));
memset(size,,sizeof(size));
memset(t,,sizeof(t));
}
void add(int x,int y){
tot++;to[tot]=y;Next[tot]=h[x];h[x]=tot;
}
void dfs(int x){
for(int i=;i<=;++i)
if(dep[x]<(<<i))break;
else fa[x][i]=fa[fa[x][i-]][i-];
for(int i=h[x];i;i=Next[i]){
int v=to[i];
if(dep[v])continue;
fa[v][]=x;
dep[v]=dep[x]+;
dfs(v);
size[x]+=size[v];
}size[x]++;
}
void dfs(int x,int ff){
pos[x]=++sz;f[x]=ff;int mx=;
for(int i=h[x];i;i=Next[i])
if(dep[to[i]]>dep[x]&&size[to[i]]>size[mx])
mx=to[i];
if(!mx)return;
dfs(mx,ff);
for(int i=h[x];i;i=Next[i])
if(dep[to[i]]>dep[x]&&mx!=to[i])
dfs(to[i],to[i]);
}
int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
int d=dep[x]-dep[y];
for(int i=;i<=;++i)
if(d&(<<i))
x=fa[x][i];
if(x==y)return x;
for(int i=;i>=;--i)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
if(x==y)return x;
return fa[x][];
}
#define L(k) (k<<1)
#define R(k) (k<<1|1)
void pushdown(int k){
if(t[k].md){
t[L(k)].md^=;t[R(k)].md^=;
t[L(k)].ld^=;t[R(k)].ld^=;
t[L(k)].rd^=;t[R(k)].rd^=;
t[k].md=;
}
if(t[k].mb){
t[L(k)].mb^=;t[R(k)].mb^=;
t[L(k)].w=t[L(k)].s-t[L(k)].w;
t[R(k)].w=t[R(k)].s-t[R(k)].w;
t[L(k)].lb^=;t[R(k)].lb^=;
t[k].mb=;
}
}
void update(int k){
node a=t[k];
t[k]=t[L(k)]+t[R(k)];
t[k].mb=a.mb;
t[k].md=a.md;
}
void build(int k,int l,int r){
if(l==r)return;
int mid=(l+r)>>;
build(L(k),l,mid);
build(R(k),mid+,r);
update(k);
}
void change1(int k,int l,int r,int x,int y){
if(x<=l&&r<=y){
t[k].mb^=;
t[k].w=t[k].s-t[k].w;
t[k].lb^=;
return;
}
pushdown(k);
int mid=(l+r)>>;
if(x<=mid)change1(L(k),l,mid,x,y);
if(y>mid)change1(R(k),mid+,r,x,y);
update(k);
}
void work1(int x,int y){
int k=lca(x,y);
while(f[x]!=f[k]){
change1(,,n,pos[f[x]],pos[x]);x=fa[f[x]][];
}if(x!=k)change1(,,n,pos[k]+,pos[x]);
while(f[y]!=f[k]){
change1(,,n,pos[f[y]],pos[y]);y=fa[f[y]][];
}if(y!=k)change1(,,n,pos[k]+,pos[y]);
}
void change2(int k,int l,int r,int x,int y){
if(x<=l&&r<=y){
t[k].md^=;
t[k].ld^=;
t[k].rd^=;
return;
}
pushdown(k);
int mid=(l+r)>>;
if(x<=mid)change2(L(k),l,mid,x,y);
if(y>mid)change2(R(k),mid+,r,x,y);
update(k);
}
void work2(int x,int y){
int k=lca(x,y);
while(f[x]!=f[k]){
change2(,,n,pos[f[x]],pos[x]);x=fa[f[x]][];
}if(x!=k)change2(,,n,pos[k]+,pos[x]);
while(f[y]!=f[k]){
change2(,,n,pos[f[y]],pos[y]);y=fa[f[y]][];
}change2(,,n,pos[k],pos[y]);
}
node ask(int k,int l,int r,int x,int y){
if(x<=l&&r<=y)return t[k];
pushdown(k);
int mid=(l+r)>>;
node ans;ans.clear();int flag=;
if(x<=mid)ans=ask(L(k),l,mid,x,y),flag=;
if(y>mid){
if(flag)ans=ans+ask(R(k),mid+,r,x,y);
else ans=ask(R(k),mid+,r,x,y);
}
update(k);
return ans;
}
int ask(int k,int l,int r,int x){
if(l==r)return t[k].ld;
pushdown(k);
int mid=(l+r)>>;
int ans;
if(x<=mid)ans=ask(L(k),l,mid,x);
else ans=ask(R(k),mid+,r,x);
update(k);
return ans;
}
node work3(int k,int x){
node ans;ans.clear();
int flag=;
while(f[x]!=f[k]){
if(flag)ans=ask(,,n,pos[f[x]],pos[x])+ans;
else ans=ask(,,n,pos[f[x]],pos[x]);
flag=;x=fa[f[x]][];
}
if(x!=k){
if(flag)ans=ask(,,n,pos[k]+,pos[x])+ans;
else ans=ask(,,n,pos[k]+,pos[x]);
}
return ans;
}
void getans(int x,int y){
int k=lca(x,y);
node L=work3(k,x);
node R=work3(k,y);
int tmp=ask(,,sz,pos[k]);
int ans=L.w+R.w;
if(x!=k)ans+=(L.lb^L.ld^tmp);
if(y!=k)ans+=(R.lb^R.ld^tmp);
printf("%d\n",ans);
}
int main(){
int T;scanf("%d",&T);
while(T--){
mem();
n=read();
for(int i=;i<n;++i){
int a=read(),b=read();
add(a,b);add(b,a);
}
dep[]=;dfs();
dfs(,);
build(,,sz);
q=read();
for(int i=;i<=q;++i){
int opt=read(),a=read(),b=read();
if(opt==)work1(a,b);
if(opt==)work2(a,b);
if(opt==)getans(a,b);
}
}
return ;
}
hdu 4897 Little Devil I的更多相关文章
- HDU 4897 Little Devil I(树链剖分)(2014 Multi-University Training Contest 4)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4897 Problem Description There is an old country and ...
- hdu 4897 Little Devil I (树链剖分+线段树)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4897 题意: 给你一棵树,一开始每条边都是白色,有三种操作: 1.将 u - v路径上的边转换颜色 ...
- HDU 4897 Little Devil I 树链剖分+线段树
Little Devil I Problem Description There is an old country and the king fell in love with a devil. T ...
- hdu 4897 树链剖分(重轻链)
Little Devil I Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- hdu 4857 Little Devil I
http://acm.hdu.edu.cn/showproblem.php?pid=4897 题意:给你一棵树,边的颜色要么为白色,要么为黑色,初始每条边为白色,有三种操作 1.将u-v链上面的所有边 ...
- 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)
题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...
- hdu 4899 Hero meet devil
传送阵:http://acm.hdu.edu.cn/showproblem.php?pid=4899 题目大意:给定一个DNA序列,求有多少长度为m的序列与该序列的最长公共子序列长度为0,1...|S ...
- HDU 4899 Hero meet devil(状压DP)(2014 Multi-University Training Contest 4)
Problem Description There is an old country and the king fell in love with a devil. The devil always ...
- HDU 4899 Hero meet devil (状压DP, DP预处理)
题意:给你一个基因序列s(只有A,T,C,G四个字符,假设长度为n),问长度为m的基因序列s1中与给定的基因序列LCS是0,1......n的有多少个? 思路:最直接的方法是暴力枚举长度为m的串,然后 ...
随机推荐
- PHP入门 - - 07-->HTML的表单
一.<form>标签及其属性 <from></form>标签对用来创建一个表单,即定义表单的开始和结束位置,<form>标签具有下面等属性. ...
- ADB常用的几个命令
1. 查看设备 adb devices 查看当前连接的设备, 连接到计算机的android设备或者模拟器将会列出显示 2. 安装软件 adb install [-r] [-s] <file> ...
- MATLAB plot函数的一些参数
直接从帮助文档中抓图,注意是颜色.线型什么的.
- express-3 最佳实践
版本控制 版本控制有以下益处: 文档: 能够回溯项目的历史,回顾所做的决策及组件的开发顺序,可形成宝贵的文档.记录项目的历史是十分有价值的. 归属: 团队工作,分工清晰,节省沟通成本. 试验: 你可以 ...
- PHP 下载简历
下载简历:先生成html模版,然后在下载转化为word格式: 获取数据方法: 先获取数据,然后开启缓存,写入数据,关闭缓存:然后下载成word: /** * 下载简历--简单 * @author La ...
- vs2010 安装MVC 3.0
下载链接如下: MVC 3安装包:http://www.microsoft.com/downloads/zh-cn/details.aspx?familyid=d2928bc1-f48c-4e95-a ...
- Post请求
写在前面的话: XMLHttpRequest对象的open方法的第一个参数为request-type,取值可以为get或post.本篇介绍post请求. 使用post方式时,浏览器会把各表单中字段元素 ...
- BZOJ4117 : [Wf2015]Weather Report
一种天气情况的概率只与4种天气的出现次数有关,故将相同概率的情况计数后放入堆中模拟哈夫曼树即可. 每次取出概率最小的,将它个数除以2,对于零头需要特判. #include<cstdio> ...
- BZOJ4504 : K个串
从左往右枚举右端点,用一棵线段树维护每个左端点的去重后的区间和. 那么对于$a[r]$,需要在$[pre[a[r]]+1,r]$里区间加上$a[r]$. 将线段树可持久化,并维护区间最大值,就可以在线 ...
- [转]error while loading shared libraries 错误解决办法总结
http://blog.csdn.net/wallwind/article/details/7580659 错误信息: error while loading shared libraries: li ...