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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【牛客 - 272B】Xor Path(树上操作,路径异或值)

發(fā)布時(shí)間:2023/12/10 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【牛客 - 272B】Xor Path(树上操作,路径异或值) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題干:

給定一棵n個(gè)點(diǎn)的樹,每個(gè)點(diǎn)有權(quán)值。定義表示? 到? 的最短路徑上,所有點(diǎn)的點(diǎn)權(quán)異或和。

對(duì)于,求所有的異或和。

?

輸入描述:

?

第一行一個(gè)整數(shù)n。

接下來n-1行,每行2個(gè)整數(shù)u,v,表示u,v之間有一條邊。

第n+1行有n個(gè)整數(shù),表示每個(gè)點(diǎn)的權(quán)值。

輸出描述:

輸出一個(gè)整數(shù),表示所有的異或和,其中。

?

示例1

輸入

復(fù)制

4 1 2 1 3 1 4 1 2 3 4

輸出

復(fù)制

5

說明

?

再將這6個(gè)數(shù)異或起來就可以得到答案5了。

備注:

題目大意:

? ? ? 每個(gè)頂點(diǎn)的點(diǎn)權(quán)為Ai,任意兩點(diǎn)路徑上點(diǎn)權(quán)異或和為Path(i,j),求所有路徑的Path(i,j)的異或和。

解題報(bào)告:

? ?比較套路的一道題,。,算一下每個(gè)節(jié)點(diǎn)的貢獻(xiàn)就行了。牽扯異或了所以肯定要看是否會(huì)有重復(fù)操作(因?yàn)閷?duì)這個(gè)點(diǎn)進(jìn)行兩次異或就會(huì)使得原結(jié)果不變)

一個(gè)題解:

考慮每個(gè)頂點(diǎn),有三種情況被用到

1.本身和其他頂點(diǎn):n-1

2.該頂點(diǎn)上面的頂點(diǎn)(k)和下面的頂點(diǎn)(m)通過該點(diǎn)進(jìn)行連接:k*m

3.該頂?shù)紫旅娴捻旤c(diǎn)通過該點(diǎn)進(jìn)行連接(上面頂點(diǎn)不用的原因是:從上層層下來,已經(jīng)記錄過。):任意兩個(gè)子樹個(gè)數(shù)相乘之和。(比較難想,,注意一下使用一個(gè)技巧: 只有 奇數(shù)*奇數(shù) 才=奇數(shù),,就方便思考了)

第三種情況直接算會(huì)超時(shí),我們需要優(yōu)化一下,考慮下如果子樹個(gè)數(shù)為偶數(shù)相當(dāng)于沒有貢獻(xiàn),所以只要考慮子樹個(gè)數(shù)為奇數(shù)的即可,最后判斷下C(cnt,2)是否為奇數(shù),奇數(shù)的話貢獻(xiàn)+1。

AC代碼:(500-700ms第一次交TLE了、、)

#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair #define fi first #define se second using namespace std; const int MAX = 7e5 + 5; vector<int> vv[MAX]; ll dp[MAX],ans; ll a[MAX]; int n; ll dfs(int cur,int rt) {int up = (int)vv[cur].size();ll tmp,cnt=0,sum=0;for(int i = 0; i<up; i++) {int v = vv[cur][i];if(v == rt) continue;tmp = dfs(v,cur);dp[cur] += tmp; if(tmp%2==1) cnt++;}if((cnt*(cnt-1)/2)%2) sum++;sum+=n-1;sum+= (dp[cur]-1) * (n - dp[cur]); // sum=(sum+(n-1)+(dp[cur]-1)*(n-dp[cur])%2)%2; 用這一行也可以AC、、、if(sum%2==1) ans ^= a[cur];return dp[cur]; } int main() {cin>>n;for(int i = 1,u,v; i<=n-1; i++) {scanf("%d%d",&u,&v);vv[u].pb(v);vv[v].pb(u);} for(int i = 1; i<=n; i++) scanf("%lld",a+i),dp[i]=1;dfs(1,-1);printf("%lld\n",ans);return 0 ;}

總結(jié):

? 這題剛開始沒有初始化dp[i]=1,,倒置用注釋和不用注釋的結(jié)果不一樣,我當(dāng)時(shí)還在想為什么會(huì)不一樣,,因?yàn)樵谀娜∧?yīng)該都一樣啊,,后來發(fā)現(xiàn)是因?yàn)閐p[cur]-1?那里就變成-1了,,所以先取模和后驅(qū)魔結(jié)果才會(huì)不一樣,,雖然都不是正確結(jié)果但是當(dāng)時(shí)句式想研究一下為什么兩種方式會(huì)得出不一樣的結(jié)果,現(xiàn)在知道了,,并且dp[i]顯然要賦值為1啊。。

再附一個(gè)快的飛起的短代碼:(177ms)

#include<bits/stdc++.h> #define ll long long #define N 500010 using namespace std; template <typename T> void read(T &x){x=0;char c=getchar();int fh=1;while (!isdigit(c)){if (c=='-')fh=-1;c=getchar();}while (isdigit(c))x=x*10+c-'0',c=getchar();x*=fh; } struct Info{int nu,ne;}a[N*2]; int b[N],num,x,y,v[N],n; ll si[N],ansn; void jb(int x,int y){a[++num].nu=y;a[num].ne=b[x];b[x]=num;} void dfs(int x,int fa){ll sum=0;si[x]=1;for (int y=b[x];y;y=a[y].ne){if (a[y].nu!=fa){dfs(a[y].nu,x);sum=sum+si[a[y].nu]*si[x];si[x]+=si[a[y].nu];}}sum=sum+si[x]*(n-si[x]);if (sum%2==1)ansn^=v[x]; } int main(){read(n);for (int i=1;i<n;i++){read(x);read(y);jb(x,y);jb(y,x);}for (int i=1;i<=n;i++){read(v[i]);}dfs(1,0);cout<<ansn<<endl;return 0; }

std:

#include <cstdio> #include <cctype> #include <algorithm> #define gc() getchar() typedef long long LL; const int N=1e6+5;int n,Ans,Enum,H[N],nxt[N<<1],to[N<<1],A[N],sz[N];inline int read() {int now=0;register char c=gc();for(;!isdigit(c);c=gc());for(;isdigit(c);now=now*10+c-'0',c=gc());return now; } inline void AE(int u,int v) {to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum; } void DFS(int x,int fa) {sz[x]=1;for(int i=H[x],v; i; i=nxt[i])if((v=to[i])!=fa) DFS(v,x), sz[x]+=sz[v];LL tmp=n-sz[x];//不經(jīng)過x的子樹的路徑for(int s=n-sz[x]+1,i=H[x],v; i; i=nxt[i])if((v=to[i])!=fa) tmp+=1ll*s*sz[v], s+=sz[v];//經(jīng)過v這個(gè)孩子節(jié)點(diǎn)的 那一串子樹的。再累加。(話說,,為啥不會(huì)爆longlong呢?)if(tmp&1) Ans^=A[x]; } int main() {n=read();for(int i=1; i<n; ++i) AE(read(),read());for(int i=1; i<=n; ++i) A[i]=read();DFS(1,1), printf("%d\n",Ans);fclose(stdin), fclose(stdout);return 0; }

?

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的【牛客 - 272B】Xor Path(树上操作,路径异或值)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。