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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

2019 ICPC Asia Nanchang Regional K.Tree 树上启发式合并 + 动态开点线段树

發(fā)布時間:2023/12/4 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2019 ICPC Asia Nanchang Regional K.Tree 树上启发式合并 + 动态开点线段树 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

傳送門

文章目錄

  • 題意:
  • 思路:

題意:

給你一棵樹,每個點(diǎn)都有一個權(quán)值valvalval,求滿足以下條件
(1)x!=yx!=yx!=y
(2)xxxyyy不互為祖先
(3)val[lca(x,y)]?2=val[x]+val[y]val[lca(x,y)]*2=val[x]+val[y]val[lca(x,y)]?2=val[x]+val[y]
(4)len(x,y)<=klen(x,y)<=klen(x,y)<=k
(x,y)(x,y)(x,y)的對數(shù)。

思路:

可以發(fā)現(xiàn)這個點(diǎn)對是可以轉(zhuǎn)換成一顆子樹的問題來遞歸解決的,他們以這個子樹的根為lcalcalca,讓后兩個點(diǎn)一定存在于子樹的不同分支里面,碰到子樹問題我們自然的想到用dsudsudsu來解決。
當(dāng)我們要更新一顆子樹的時候,當(dāng)前子樹的重兒子的信息已經(jīng)存起來了,我們只需要依次遍歷計算其他分支,讓后更新其他分支的信息。要注意必須先遍歷計算才能更新,這樣才能保證算出來的一定是根的不同分支里的對數(shù)。讓后還有一個問題,就是怎么算答案呢?我們更新的時候是將depth[u]depth[u]depth[u]val[u]val[u]val[u]一起放到要更新的數(shù)組里面的,我們查詢的時候要查詢權(quán)值為val[rt]?2?val[now]val[rt]*2-val[now]val[rt]?2?val[now]且深度<=depth[rt]+k?(depth[now]?depth[rt])<=depth[rt]+k-(depth[now]-depth[rt])<=depth[rt]+k?(depth[now]?depth[rt])的點(diǎn)對。顯然普通數(shù)據(jù)結(jié)構(gòu)不好維護(hù),所以我們可以對每個權(quán)值開一顆權(quán)值線段樹,讓后動態(tài)開點(diǎn)就好啦,就是有點(diǎn)不好調(diào)。
最后答案乘二即可。

//#pragma GCC optimize(2) #include<cstdio> #include<iostream> #include<string> #include<cstring> #include<map> #include<cmath> #include<cctype> #include<vector> #include<set> #include<queue> #include<algorithm> #include<sstream> #include<ctime> #include<cstdlib> #define X first #define Y second #define L (u<<1) #define R (u<<1|1) #define pb push_back #define mk make_pair #define Mid (tr[u].l+tr[u].r>>1) #define Len(u) (tr[u].r-tr[u].l+1) #define random(a,b) ((a)+rand()%((b)-(a)+1)) #define db puts("---") using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); } //void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); } //void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL; typedef unsigned long long ULL; typedef pair<LL,LL> PII;const int N=200010,mod=1e9+7,INF=0x3f3f3f3f; const double eps=1e-6;int n,k; vector<int>v[N]; int val[N]; LL cnt,ans[N]; int depth[N],se[N],son[N]; int root[N],idx; struct Node {int l,r;int cnt; }tr[N*40];void modify(int &rt,int l,int r,int x,int tag) {if(!rt) rt=++idx;if(l==r) { tr[rt].cnt+=tag; return; }int mid=l+r>>1;if(x<=mid) modify(tr[rt].l,l,mid,x,tag);else modify(tr[rt].r,mid+1,r,x,tag);tr[rt].cnt=tr[tr[rt].l].cnt+tr[tr[rt].r].cnt; }int query(int rt,int l,int r,int ql,int qr) {if(!rt) return 0;if(l>=ql&&r<=qr) return tr[rt].cnt;int mid=l+r>>1;int ans=0;if(ql<=mid) ans+=query(tr[rt].l,l,mid,ql,qr);if(qr>mid) ans+=query(tr[rt].r,mid+1,r,ql,qr);return ans; }void dfs_son(int u,int fa) {se[u]=1; depth[u]=depth[fa]+1;for(auto x:v[u]){if(x==fa) continue;dfs_son(x,u);se[u]+=se[x];if(se[x]>se[son[u]]) son[u]=x;} }void update(int u,int fa,int son,int tag) {modify(root[val[u]],1,n,depth[u],tag);for(auto x:v[u]){if(x==fa||x==son) continue;update(x,u,son,tag);} }void solve(int u,int fa,int son,int rt) {if(val[rt]*2-val[u]>=0&&val[rt]*2-val[u]<=n&&depth[rt]+k-(depth[u]-depth[rt])>=depth[rt]+1) cnt+=query(root[val[rt]*2-val[u]],1,n,depth[rt]+1,min(depth[rt]+k-(depth[u]-depth[rt]),n));//cnt+=mp[{depth[rt]+k-(depth[u]-depth[rt]),val[rt]*2-val[u]}];for(auto x:v[u]){if(x==fa||x==son) continue;solve(x,u,son,rt);} }void dfs(int u,int fa,int op) {for(auto x:v[u]){if(x==fa||x==son[u]) continue;dfs(x,u,0);}if(son[u]) dfs(son[u],u,1);for(auto x:v[u]){if(x==fa||x==son[u]) continue;solve(x,u,son[u],u); update(x,u,son[u],1);}modify(root[val[u]],1,n,depth[u],1);ans[u]=cnt; cnt=0;if(!op) update(u,fa,-1,-1); }int main() { // ios::sync_with_stdio(false); // cin.tie(0);scanf("%d%d",&n,&k);for(int i=1;i<=n;i++) scanf("%d",&val[i]);for(int i=2;i<=n;i++){int x; scanf("%d",&x);v[x].pb(i);}dfs_son(1,0);dfs(1,0,1);LL sum=0;for(int i=1;i<=n;i++) sum+=ans[i];printf("%lld\n",sum*2);return 0; } /* 4 3 1 1 3 2 1 1 2 */

總結(jié)

以上是生活随笔為你收集整理的2019 ICPC Asia Nanchang Regional K.Tree 树上启发式合并 + 动态开点线段树的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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