BZOJ1782[USACO 2010 Feb Gold 3.Slowing down]——dfs+treap
生活随笔
收集整理的這篇文章主要介紹了
BZOJ1782[USACO 2010 Feb Gold 3.Slowing down]——dfs+treap
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目描述
每天Farmer John的N頭奶牛(1 <= N <= 100000,編號1…N)從糧倉走向他的自己的牧場。牧場構成了一棵樹,糧倉在1號牧場。恰好有N-1條道路直接連接著牧場,使得牧場之間都恰好有一條路徑相連。第i條路連接著A_i,B_i,(1 <= A_i <= N; 1 <= B_i <= N)。奶牛們每人有一個私人牧場P_i (1 <= P_i <= N)。糧倉的門每次只能讓一只奶牛離開。耐心的奶牛們會等到他們的前面的朋友們到達了自己的私人牧場后才離開。首先奶牛1離開,前往P_1;然后是奶牛2,以此類推。當奶牛i走向牧場P_i時候,他可能會經過正在吃草的同伴旁。當路過已經有奶牛的牧場時,奶牛i會放 慢自己的速度,防止打擾他的朋友。 考慮如下的牧場結構(括號內的數字代表了牧場的所有者)。輸入
* 第1行 : 一個正整數N * 第2…N行: 第i+1行包括一對正整數A_i,B_i * 第N+1..N+N行: 第 N+i行 包括一個正整數: P_i輸出
* 第一行到第N行:第i行表示第i只奶牛需要被放慢的次數樣例輸入
51 4
5 4
1 3
2 4
4
2
1
5
3
樣例輸出
01
0
2
1
題目大意就是求每個點到根節點的鏈上有幾個點的點權(就是奶牛編號)比這個點小??雌渌硕际鞘裁茨脴錉顢到M、樹鏈剖分、線段樹過的。最近寫平衡樹比較爽的我就拿treap寫了一下。首先求一條鏈(也就是一個數列)上比這個數小的數有多少個,直接求一下當前數在數列中的排名就好了,這個直接裸上treap。但因為只考慮這條鏈上的點,所以要在每次回溯到一個點時把這個點從treap中刪除。 最后附上代碼。 #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; int n; int x,y; int tot; int root; int a[100010]; int s[100010]; int r[300010]; int v[300010]; int g[100010]; int to[200010]; int ls[300010]; int rs[300010]; int head[100010]; int next[200010]; int size[300010]; void add(int x,int y) {tot++;next[tot]=head[x];head[x]=tot;to[tot]=y; } void up(int x) {size[x]=size[rs[x]]+size[ls[x]]+1; } void rturn(int &x) {int t;t=ls[x];ls[x]=rs[t];rs[t]=x;size[t]=size[x];up(x);x=t; } void lturn(int &x) {int t;t=rs[x];rs[x]=ls[t];ls[t]=x;size[t]=size[x];up(x);x=t; } void insert_sum(int x,int &i) {if(!i){i=++tot;size[i]=1;v[i]=x;r[i]=rand();return ;}size[i]++;if(x>v[i]){insert_sum(x,rs[i]);if(r[rs[i]]<r[i]){lturn(i);}}else{insert_sum(x,ls[i]);if(r[ls[i]]<r[i]) {rturn(i);}}return ; } void delete_sum(int x,int &i) {if(i==0){return ;}if(v[i]==x){if((ls[i]*rs[i])==0){i=ls[i]+rs[i];}else if(r[ls[i]]<r[rs[i]]){rturn(i);delete_sum(x,i);}else{lturn(i);delete_sum(x,i);}return ;}size[i]--;if(v[i]<x){delete_sum(x,rs[i]);}else{delete_sum(x,ls[i]);}return ; } int ask_num(int x,int i) {if(i==0){return 0;}if(v[i]==x){return size[ls[i]]+1;}if(v[i]<x){return ask_num(x,rs[i])+size[ls[i]]+1;}return ask_num(x,ls[i]); } void dfs(int x,int fa) {for(int i=head[x];i;i=next[i]){if(to[i]!=fa){g[s[to[i]]]=ask_num(s[to[i]],root);insert_sum(s[to[i]],root);dfs(to[i],x);delete_sum(s[to[i]],root);}} } int main() {srand(12378);scanf("%d",&n);for(int i=1;i<n;i++){scanf("%d%d",&x,&y);add(x,y);add(y,x);}for(int i=1;i<=n;i++){scanf("%d",&a[i]);s[a[i]]=i;}insert_sum(s[1],root);g[s[1]]=0;dfs(1,1);for(int i=1;i<=n;i++){printf("%d\n",g[i]);} }
轉載于:https://www.cnblogs.com/Khada-Jhin/p/9147365.html
總結
以上是生活随笔為你收集整理的BZOJ1782[USACO 2010 Feb Gold 3.Slowing down]——dfs+treap的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端基础(一):js数据类型
- 下一篇: 迟到两年,Lu1与Cee合作的经典单曲《