传送阵: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的更多相关文章

  1. 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 ...

  2. hdu 4897 Little Devil I (树链剖分+线段树)

    题目链接:  http://acm.hdu.edu.cn/showproblem.php?pid=4897 题意: 给你一棵树,一开始每条边都是白色,有三种操作: 1.将 u - v路径上的边转换颜色 ...

  3. 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 ...

  4. hdu 4897 树链剖分(重轻链)

    Little Devil I Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  5. hdu 4857 Little Devil I

    http://acm.hdu.edu.cn/showproblem.php?pid=4897 题意:给你一棵树,边的颜色要么为白色,要么为黑色,初始每条边为白色,有三种操作 1.将u-v链上面的所有边 ...

  6. 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)

    题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...

  7. hdu 4899 Hero meet devil

    传送阵:http://acm.hdu.edu.cn/showproblem.php?pid=4899 题目大意:给定一个DNA序列,求有多少长度为m的序列与该序列的最长公共子序列长度为0,1...|S ...

  8. 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 ...

  9. HDU 4899 Hero meet devil (状压DP, DP预处理)

    题意:给你一个基因序列s(只有A,T,C,G四个字符,假设长度为n),问长度为m的基因序列s1中与给定的基因序列LCS是0,1......n的有多少个? 思路:最直接的方法是暴力枚举长度为m的串,然后 ...

随机推荐

  1. JDK 伪异步编程(线程池)

    伪异步IO编程 BIO主要的问题在于每当有一个新的客户端请求接入时,服务端必须创建一个新的线程处理新接入的客户端链路,一个线程只能处理一个客户端连接.在高性能服务器应用领域,往往需要面向成千上万个客户 ...

  2. ubuntu 下python版本切换

    1. 安装ubuuntu 14.04之后python的默认版本为2.7.6但是我想使用python的版本为3.4 可以打开终端:输入:alias python = python3

  3. 手持终端打印POS机(安装移动销售开单订货会软件)无线传输到订货会后台销售管理系统

    当今的服装市场是品牌竞争时代,产品能否紧随潮流前线并迅速推出市场抢得先机,是品牌成功与否的关键.而订货会是每个鞋服企业新产品走向市场至关重要的开端,订货会如何演绎.成功与否,与品牌在竞争洪流中的命运息 ...

  4. (转)POJ题目分类

    初期:一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推. ...

  5. Shell 编程基础之基本语法结构汇总

    一.条件语句 简单条件 if [ condition ]; then # 当 condition 成立时,执行内容: fi # 将 if 反过来写,fi 结束 if 之意 复杂条件 if [ cond ...

  6. React的第一步

    首先了解React中所牵扯到的几个重要的概念 什么是React? 是Facebook的开发团队开发出来的一个用于构建用户界面个js库,最近才开源出来公布于世,它的初衷是用于创建“独立的视图组件”,一个 ...

  7. sql over的作用及用法

    over不能单独使用,要和分析函数:rank(),dense_rank(),row_number()等一起使用.其参数:over(partition by columnname1 order by c ...

  8. BZOJ4356 : Ceoi2014 Wall

    求出左上角到每个需要保护的点左上角的最短路树,那么最优解一定圈住了它们. 然后将每个点拆成四个点,四个点之间如果没跨越最短路树的树边,那就连0权边. 每个需要保护的点四周4个点都不可通行,求出最短路即 ...

  9. datanode启动不了

    报如下异常:*org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.hdfs.server.protocol.DisallowedDatano ...

  10. Jaxb 解析 带有继承关系的bean与xml

    具体方法: 1. 在jaxb的setClasstobebounds中,只需要子类的class,无需父类. 2. 父类的前面加如下声明: @XmlAccessorType(XmlAccessType.F ...