国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

hdu 1512 左偏樹

2019-11-11 05:54:19
字體:
來源:轉載
供稿:網友

題目:

Monkey King

Time Limit: 10000/5000 MS (java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5571    Accepted Submission(s): 2395PRoblem DescriptionOnce in a forest, there lived N aggressive monkeys. At the beginning, they each does things in its own way and none of them knows each other. But monkeys can't avoid quarrelling, and it only happens between two monkeys who does not know each other. And when it happens, both the two monkeys will invite the strongest friend of them, and duel. Of course, after the duel, the two monkeys and all of there friends knows each other, and the quarrel above will no longer happens between these monkeys even if they have ever conflicted.Assume that every money has a strongness value, which will be reduced to only half of the original after a duel(that is, 10 will be reduced to 5 and 5 will be reduced to 2).And we also assume that every monkey knows himself. That is, when he is the strongest one in all of his friends, he himself will go to duel. InputThere are several test cases, and each case consists of two parts.First part: The first line contains an integer N(N<=100,000), which indicates the number of monkeys. And then N lines follows. There is one number on each line, indicating the strongness value of ith monkey(<=32768).Second part: The first line contains an integer M(M<=100,000), which indicates there are M conflicts happened. And then M lines follows, each line of which contains two integers x and y, indicating that there is a conflict between the Xth monkey and Yth. OutputFor each of the conflict, output -1 if the two monkeys know each other, otherwise output the strongness value of the strongest monkey in all friends of them after the duel. Sample Input
520161010452 33 43 54 51 5 Sample Output
855-110

分析:

每一只猴子看做一個結點,建立左偏樹,樹根維護最大值。若兩結點樹根相同,說明兩只猴子是朋友,輸出-1;

否則,兩根節點值減半,刪除,重新與原樹合并得兩新樹,兩新樹合并后返回根節點值。

本題僅涉及到左偏樹部分操作。

左偏樹入門:

http://wenku.baidu.com/view/1c18eff9aef8941ea76e051b.html

http://wenku.baidu.com/view/004aa1ee19e8b8f67c1cb9d4.html?from=search

http://sunmoon-template.blogspot.ca/2014_12_01_archive.html

代碼:

#include<iostream>#include<cstring>#include<cstdio>#include<cstdlib>#include<ctype.h>    //tower()#include<set>#include<iomanip>// cout<<setprecision(1)<<fixed<<a;#include<vector>   #include<time.h>  #include<assert.h>  //assert#include<cmath>	#include<algorithm>#include<bitset>#include<limits.h>#include<stack>#include<queue>using namespace std;const int maxn=100050;const int inf=INT_MAX-100;struct node{    int val,dis,lt,rt,fa;//fa 父節點}ltree[maxn];int n,q,t;void maketree(int a,int k){//結點成樹 a結點值為k     ltree[a].val=k;    ltree[a].fa=a;    ltree[a].lt=ltree[a].rt=0;    ltree[a].dis=(a==0)?-1:0;}int find(int x){//非遞歸路徑壓縮,返回所在樹根節點     int s,k,j;    s=k=x;    while(s!=ltree[s].fa) s=ltree[s].fa;    while(k!=s){        j=ltree[k].fa;        ltree[k].fa=s;        k=j;    }    return s;}int merge(int a,int b){//兩棵樹合并 改變rt,dis,fa     if(a==0) return b;    if(b==0) return a;    if(ltree[a].val<ltree[b].val) swap(a,b);    ltree[a].rt=merge(ltree[a].rt,b);//b接在a最右邊 	int &l=ltree[a].lt,&r=ltree[a].rt;//左右子樹的引用,取別名,不另占內存,值同時修改        ltree[r].fa=a;//ltree[l].fa=    if(ltree[l].dis<ltree[r].dis) swap(l,r);//維持左偏性     if(r==0) ltree[a].dis=0;	else ltree[a].dis=ltree[r].dis+1;    return a;}int solve(int a,int b){	int tmp,ta,tb;	a=find(a);	b=find(b);	if(a==b) return -1;//	ltree[ltree[a].lt].fa=ltree[a].lt;//	ltree[ltree[a].rt].fa=ltree[a].rt;	ltree[a].val>>=1;	tmp=merge(ltree[a].lt,ltree[a].rt);	ltree[a].dis=ltree[a].lt=ltree[a].rt=0;    ta=merge(tmp,a);//	ltree[ltree[b].lt].fa=ltree[b].lt;//	ltree[ltree[b].rt].fa=ltree[b].rt;	ltree[b].val>>=1; 	tmp=merge(ltree[b].lt,ltree[b].rt);	ltree[b].dis=ltree[b].lt=ltree[b].rt=0;    tb=merge(tmp,b);        tmp=merge(ta,tb);    ltree[tmp].fa=ltree[ta].fa=ltree[tb].fa=tmp;    return ltree[tmp].val;}int main(){//795MS	3540K    while(~scanf("%d",&n)){	    for(int i=1;i<=n;++i){	        scanf("%d",&t);	        maketree(i,t);	    }//	    maketree(0,0);	    scanf("%d",&q);	    int c,d;	    for(int i=0;i<q;++i){	        scanf("%d%d",&c,&d);	        printf("%d/n",solve(c,d));	    }    }    return 0;    }


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 泊头市| 武威市| 衡水市| 无极县| 灯塔市| 商水县| 蓬莱市| 新昌县| 隆德县| 芜湖县| 景德镇市| 临夏县| 闻喜县| 遵化市| 绥江县| 翁源县| 宁南县| 天峨县| 聂拉木县| 稻城县| 峨眉山市| 上饶县| 安徽省| 玉门市| 茌平县| 临洮县| 米泉市| 通河县| 资溪县| 九龙县| 宁国市| 茂名市| 平乐县| 南乐县| 天台县| 恩平市| 罗定市| 都昌县| 西畴县| 蛟河市| 黎平县|