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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Codeforces 686D. Kay and Snowflake

發布時間:2023/12/20 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Codeforces 686D. Kay and Snowflake 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.




題意:

? ? ? ?給定一顆n個節點的樹,q次詢問,每次詢問以節點x為根的子樹的重心。n,q<=300000

題解:

? ? ? ?又糊了一個和標算不一樣的做法。

? ? ? ?標算:根據重心的一個性質:把兩棵樹通過某一點相連得到一顆新的樹,新的樹的重心必然在連接原來兩棵樹重心的路徑上。對于我們從點1開始往下進行遍歷,返回的時候就可以可以看成一顆樹與另一顆樹相連求重心。

? ? ? ?我的算法:考慮以一個點為根的子樹,要么這個點為重心,要么重心在這個點最大的子樹內。將所有連接節點與其最大子樹的邊連成一條鏈,則重心就在鏈上。于是維護一個倍增數組son,son[x][i]表示以x點為起點,沿著這條鏈條跳2^i條邊到達的點,每次暴力倍增求解即可。

#include<set> #include<map> #include<queue> #include<stack> #include<cmath> #include<cstdio> #include<time.h> #include<vector> #include<cstring> #include<stdlib.h> #include<iostream> #include<algorithm> #define LL long long using namespace std; const int N=3e5+10; const int mod=1e9+7; const int inf=0x3f3f3f3f;int n,m,E,k,siz[N],fa[N]; int nex[N<<1],fir[N],arr[N<<1],son[N][23];namespace FastIO {template<typename tp> inline void read(tp &x) {x=0; register char c=getchar(); register bool f=0;for(;c<'0'||c>'9';f|=(c=='-'),c = getchar());for(;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0',c = getchar());if(f) x=-x;}template<typename tp> inline void write(tp x) {if (x==0) return (void) (putchar('0'));if (x<0) putchar('-'),x=-x;int pr[20]; register int cnt=0;for (;x;x/=10) pr[++cnt]=x%10;while (cnt) putchar(pr[cnt--]+'0');}template<typename tp> inline void writeln(tp x) {write(x);putchar('\n');} } using namespace FastIO;void Add_Edge(int x,int y) {nex[++E]=fir[x];fir[x]=E;arr[E]=y; }void dfs1(int x) {siz[x]=1;for (int i=fir[x];i;i=nex[i]) {if (arr[i]!=fa[x]) {fa[arr[i]]=x;dfs1(arr[i]);siz[x]+=siz[arr[i]];}}for (int i=fir[x];i;i=nex[i])if (arr[i]!=fa[x]) if (siz[arr[i]]>siz[son[x][0]]) {son[x][0]=arr[i];}for (int i=1;i<=20;i++)son[x][i]=son[son[x][i-1]][i-1]; }int check(int x,int y) {if (!y) return 0;return 2*siz[y]>=siz[x]; }int main() {read(n); read(m);for (int i=2;i<=n;i++) {int x; read(x);Add_Edge(x,i);Add_Edge(i,x);}dfs1(1);for (int i=1;i<=m;i++) {int x; read(x);int y=x;for (int i=20;i>=0;i--) {if ((siz[son[y][0]]+siz[son[y][0]]<=siz[x])&&(2*siz[y]>=siz[x])) break;else if (check(x,son[y][i])) y=son[y][i];}writeln(y);}return 0; }

總結

以上是生活随笔為你收集整理的Codeforces 686D. Kay and Snowflake的全部內容,希望文章能夠幫你解決所遇到的問題。

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