http://acm.hdu.edu.cn/showproblem.php?pid=4897

题意:
给你一棵树,边的颜色要么为白色,要么为黑色,初始每条边为白色,有三种操作

1、将u-v链上面的所有边的颜色翻转
2、将u-v链上面所有邻接的边翻转(边上只有一个点在链上面)
3、询问u->v上面有多少黑色的边

树链剖分,线段树维护4个信息:

按dfs序建立线段树后,如果线段树内节点的区间为[l,r],则此节点维护树上dfs序[l,r]内的父边的信息

父边指 点与父节点之间的边

sum0:节点的父边属于重链且颜色为白色 的边数

sum1:节点的父边属于重链且颜色为黑色 的边数

rev1:节点的父边颜色是否被操作1取反 (实际只会用到属于轻链的边)

rev2:节点的子树中,与节点直接相连的属于轻链边 是否被操作2取反

操作1:直接取反,交换sum0和sum1,维护标记rev1

细节:最后u和v(dep[u]<dep[v])汇集到一条重链的时候,最后一次操作不包括u,因为点代表的是父边的信息

操作2:一条链的相邻边,除了对链上的点维护rev2操作外,

链最顶端的点如果是其父节点的重儿子,需要修改它的rev1

路径上每条重链最底端的点,如果它有重儿子,需要修改它重儿子的rev1

因为标记rev2只维护轻链

操作3:重链直接查,轻链呢?

在树链剖分往上跳的时候,跳轻链一定是只跳一条边

假设这条边连接了节点u和v,dep[u]<dep[v]

如果rev2[u]^rev2[v]^rev1[v] 为 true,则这条边为黑色

clj的题就是好哇!!!

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>using namespace std;#define N 100001int n;int front[N],nxt[N<<1],to[N<<1],tot;int siz[N],dep[N],fa[N];
int bl[N],son[N];
int id[N],dy[N],cnt;bool big[N];int sum0[N<<2],sum1[N<<2];
bool rev1[N<<2],rev2[N<<2];int ans;void read(int &x)
{x=0; char c=getchar();while(!isdigit(c)) c=getchar();while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}void add(int u,int v)
{to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
}void dfs1(int x)
{siz[x]=1;for(int i=front[x];i;i=nxt[i])if(to[i]!=fa[x]){fa[to[i]]=x;dep[to[i]]=dep[x]+1;dfs1(to[i]);siz[x]+=siz[to[i]];}
}void dfs2(int x,int top)
{bl[x]=top;id[x]=++cnt;dy[cnt]=x;int y=0;for(int i=front[x];i;i=nxt[i])if(to[i]!=fa[x] && siz[to[i]]>siz[y]) y=to[i];if(y) {son[x]=y;big[y]=true;dfs2(y,top);}else return;for(int i=front[x];i;i=nxt[i])if(to[i]!=fa[x] && to[i]!=y) dfs2(to[i],to[i]);
}void down1(int k)
{rev1[k<<1]^=1;swap(sum0[k<<1],sum1[k<<1]);rev1[k<<1|1]^=1;swap(sum0[k<<1|1],sum1[k<<1|1]);rev1[k]^=1;
}void down2(int k)
{rev2[k<<1]^=1;rev2[k<<1|1]^=1;rev2[k]^=1;
}void Reverse(int k,int l,int r,int opl,int opr,int ty)
{if(l>=opl && r<=opr){if(ty==1){swap(sum1[k],sum0[k]);rev1[k]^=1;}else rev2[k]^=1;return;}int mid=l+r>>1;if(rev1[k]) down1(k);if(rev2[k]) down2(k);if(opl<=mid) Reverse(k<<1,l,mid,opl,opr,ty);if(opr>mid) Reverse(k<<1|1,mid+1,r,opl,opr,ty);if(ty==1){sum1[k]=sum1[k<<1]+sum1[k<<1|1];sum0[k]=sum0[k<<1]+sum0[k<<1|1];}
}int get_lca(int u,int v)
{while(bl[u]!=bl[v]){if(dep[bl[u]]<dep[bl[v]]) swap(u,v);u=fa[bl[u]];}return dep[u]<dep[v] ? u : v;
}bool point_query(int k,int l,int r,int x,int ty)
{if(l==r) return ty==1 ? rev1[k] : rev2[k];if(rev1[k]) down1(k);if(rev2[k]) down2(k);int mid=l+r>>1;if(x<=mid) return point_query(k<<1,l,mid,x,ty);return point_query(k<<1|1,mid+1,r,x,ty);
}void query(int k,int l,int r,int opl,int opr)
{if(l>=opl && r<=opr){ans+=sum1[k];return;}if(rev1[k]) down1(k);if(rev2[k]) down2(k);int mid=l+r>>1;if(opl<=mid) query(k<<1,l,mid,opl,opr);if(opr>mid) query(k<<1|1,mid+1,r,opl,opr);
}void solve(int ty,int u,int v)
{if(ty==1){while(bl[u]!=bl[v]){if(dep[bl[u]]<dep[bl[v]]) swap(u,v);Reverse(1,1,n,id[bl[u]],id[u],1);u=fa[bl[u]];}if(dep[u]>dep[v]) swap(u,v);if(u!=v) Reverse(1,1,n,id[u]+1,id[v],1);}else if(ty==2){int lca=get_lca(u,v);if(lca!=u && lca!=v) {if(big[lca]) Reverse(1,1,n,id[lca],id[lca],1);}else{if(dep[u]>dep[v]) swap(u,v);if(big[u]) Reverse(1,1,n,id[u],id[u],1);}while(bl[u]!=bl[v]){if(dep[bl[u]]<dep[bl[v]]) swap(u,v);if(son[u]) Reverse(1,1,n,id[son[u]],id[son[u]],1);Reverse(1,1,n,id[bl[u]],id[u],2);u=fa[bl[u]];}if(dep[u]>dep[v]) swap(u,v); if(son[v]) Reverse(1,1,n,id[son[v]],id[son[v]],1);Reverse(1,1,n,id[u],id[v],2);}else{    ans=0;        while(bl[u]!=bl[v]){if(dep[bl[u]]<dep[bl[v]]) swap(u,v);query(1,1,n,id[bl[u]],id[u]);ans+=point_query(1,1,n,id[bl[u]],2)^point_query(1,1,n,id[fa[bl[u]]],2)^point_query(1,1,n,id[bl[u]],1);u=fa[bl[u]];}if(dep[u]>dep[v]) swap(u,v);if(u!=v) query(1,1,n,id[u]+1,id[v]);printf("%d\n",ans);}
}    void build(int k,int l,int r)
{sum0[k]=sum1[k]=0;rev1[k]=rev2[k]=false;if(l==r) {sum0[k]=big[dy[l]];return;}int mid=l+r>>1;build(k<<1,l,mid);build(k<<1|1,mid+1,r);sum0[k]=sum0[k<<1]+sum0[k<<1|1];
}void clear()
{tot=cnt=0;memset(front,0,sizeof(front));memset(son,0,sizeof(son));memset(big,false,sizeof(big));
}int main()
{freopen("data.in","r",stdin);freopen("my.out","w",stdout);int T;read(T);int u,v;int ty,m,lca;while(T--){clear();read(n);for(int i=1;i<n;++i){read(u); read(v);add(u,v);}dfs1(1);dfs2(1,1);build(1,1,n);read(m);while(m--){read(ty); read(u); read(v);solve(ty,u,v);}}return 0;
}

Little Devil I

Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1087    Accepted Submission(s): 378

Problem Description
There is an old country and the king fell in love with a devil. The devil always asks the king to do some crazy things. Although the king used to be wise and beloved by his people. Now he is just like a boy in love and can’t refuse any request from the devil. Also, this devil is looking like a very cute Loli.

The devil likes to make thing in chaos. This kingdom’s road system is like simply a tree(connected graph without cycle). A road has a color of black or white. The devil often wants to make some change of this system.

In details, we call a path on the tree from a to b consists of vertices lie on the shortest simple path between a and b. And we say an edge is on the path if both its two endpoints is in the path, and an edge is adjacent to the path if exactly one endpoint of it is in the path.

Sometimes the devil will ask you to reverse every edge’s color on a path or adjacent to a path.

The king’s daughter, WJMZBMR, is also a cute loli, she is surprised by her father’s lolicon-like behavior. As she is concerned about the road-system’s status, sometimes she will ask you to tell there is how many black edge on a path.

Initially, every edges is white.

Input
The first line contains an integer T, denoting the number of the test cases.
For each test case, the first line contains an integer n, which is the size of the tree. The vertices be indexed from 1.
On the next n-1 lines, each line contains two integers a,b, denoting there is an edge between a and b.
The next line contains an integer Q, denoting the number of the operations.
On the next Q lines, each line contains three integers t,a,b. t=1 means we reverse every edge’s color on path a to b. t=2 means we reverse every edge’s color adjacent to path a to b. t=3 means we query about the number of black edge on path a to b.

T<=5.
n,Q<=10^5.
Please use scanf,printf instead of cin,cout,because of huge input.

Output
For each t=3 operation, output the answer in one line.
Sample Input
1 10 2 1 3 1 4 1 5 1 6 5 7 4 8 3 9 5 10 6 10 2 1 6 1 3 8 3 8 10 2 3 4 2 10 8 2 4 10 1 7 6 2 7 3 2 1 4 2 10 10
Sample Output
3

Hint

reverse color means change from white to black or vice virsa.

Author
WJMZBMR

转载于:https://www.cnblogs.com/TheRoadToTheGold/p/8456845.html

hdu 4857 Little Devil I相关推荐

  1. HDU 4857 拓扑排序 优先队列

    n个数,已经有大小关系,现给m个约束,规定a在b之前,剩下的数要尽可能往前移.输出序列 大小关系显然使用拓扑结构,关键在于n个数本身就有大小关系,那么考虑反向建图,优先选择值最大的入度为零的点,这样得 ...

  2. hdu 4857 逃生 拓扑排序

    逃生 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4857 Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只 ...

  3. HDU 4857 逃生 (反向拓扑排序 容器实现)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 逃生 Time Limit: 2000/1000 MS (Java/Others)    Mem ...

  4. (HDU - 4857)逃生(拓扑+思维)

    题目链接:Problem - 4857 (hdu.edu.cn) 本题就是让我们在他给定的前后顺序前提下求出对应的拓扑排序,要保证小号尽量靠前. 我刚开始做这道题目时就直接认为这就是一个拓扑排序模板, ...

  5. HDU 4857 Couple doubi(找循环节)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4861 解题报告:桌子上有k个球 ,第i个球的价值wi = 1^i+2^i+...+(p-1)^i (m ...

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

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

  7. HDU 4857 逃生(拓扑排序)

    拓扑排序 一.定义 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若<u,v> ∈ ...

  8. HDU 4857 逃生 【拓扑排序+反向建图+优先队列】

    逃生 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission ...

  9. HDU 4857 逃生 拓扑排序好题 第一次做CLJ出的题

    逃生 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b ...

最新文章

  1. 【Linux 驱动】第九章 与硬件通信
  2. 机器学习研究今年谁最火?几何深度学习成最大赢家,Reddit为提名选手吵成一团...
  3. Infiniband网络抓包
  4. java.lang.UnsupportedOperationException: Can't convert to dimension: type=0x12问题
  5. 我的Go+语言初体验——(2)IDE 详细安装教程
  6. 获取表单对象,得三种方法getElementById(), getElementsByName(), and getElementsByTagName() 和用法...
  7. windows定时任务python shutil_python- shutil 高级文件操作
  8. non thread safe php vc11,PHP 中什么线程安全(TS)和非线程安全(NTS)
  9. 28 POSIX Threads
  10. Spring Cloud 中的@FeignClient注解中的contextId属性
  11. 【转】查看linux服务器的系统信息
  12. 贝叶斯网络(概率图模型)
  13. 太牛了!阿里p8全面透彻剖析《Netty权威指南》,程序员必看!
  14. Arduino基础2
  15. css中文字段落对齐,CSS段落对齐方式
  16. Android Studio设置关闭当前页面的快捷键ctrl+w
  17. 牡丹江java奔腾有知道的吗_老转盘道和“奔腾广场”之间,藏着多少个日新月异?...
  18. Redis Srem 命令
  19. 光纤收发器的原理及应用_光纤收发器工作原理 - 光纤收发器工作原理及技术详解(分类,使用方法及接线图)...
  20. 关于串口编程的(一)

热门文章

  1. Java Stream(流)的分类, 四大基本流的介绍
  2. java velocity是什么意思,什么是Apache Velocity?
  3. 如何使用 Kubernetes 监测定位慢调用
  4. What‘s new in dubbo-go v1.5.6
  5. 电脑字体模糊_2020年初电脑配件和配置单推荐!
  6. Fiddler之Autoresponder替换(Web)
  7. html的表单图形验证码怎么做,form表单验证加验证码.html
  8. cad中拖动文字时卡顿_技巧CAD制图的一百多个技巧,都学会你就逆天了!(下)...
  9. java数据类型划分_一张图搞定java数据类型的划分
  10. oracle 安全桌面,Oracle Secure Global Desktop组件远程漏洞(CVE-2012-1685)