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

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

hdu 1512 左偏樹

2019-11-11 05:05:40
字體:
供稿:網(wǎng)友

題目:

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

分析:

每一只猴子看做一個(gè)結(jié)點(diǎn),建立左偏樹,樹根維護(hù)最大值。若兩結(jié)點(diǎn)樹根相同,說明兩只猴子是朋友,輸出-1;

否則,兩根節(jié)點(diǎn)值減半,刪除,重新與原樹合并得兩新樹,兩新樹合并后返回根節(jié)點(diǎn)值。

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

左偏樹入門:

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 父節(jié)點(diǎn)}ltree[maxn];int n,q,t;void maketree(int a,int k){//結(jié)點(diǎn)成樹 a結(jié)點(diǎn)值為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){//非遞歸路徑壓縮,返回所在樹根節(jié)點(diǎn)     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){//兩棵樹合并 改變r(jià)t,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;//左右子樹的引用,取別名,不另占內(nèi)存,值同時(shí)修改        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;    }


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 普定县| 增城市| 林周县| 莱芜市| 南岸区| 罗山县| 唐河县| 夏河县| 海原县| 沁阳市| 建瓯市| 民勤县| 高淳县| 台东县| 泸溪县| 伊春市| 门头沟区| 江口县| 高平市| 娄底市| 江达县| 永嘉县| 邛崃市| 馆陶县| 徐州市| 奉贤区| 饶河县| 怀化市| 绥江县| 墨玉县| 时尚| 兴仁县| 肥西县| 油尖旺区| 东光县| 华宁县| 涞源县| 涞源县| 平罗县| 达日县| 崇信县|