日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

hdu 4857 Little Devil I

發布時間:2025/3/20 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hdu 4857 Little Devil I 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的hdu 4857 Little Devil I的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。