• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            ACM___________________________

            ______________白白の屋
            posts - 182, comments - 102, trackbacks - 0, articles - 0
            <2010年8月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            2930311234

            常用鏈接

            留言簿(24)

            隨筆分類(332)

            隨筆檔案(182)

            FRIENDS

            搜索

            積分與排名

            最新隨筆

            最新評論

            閱讀排行榜

            評論排行榜

            MiYu原創(chuàng), 轉帖請注明 : 轉載自 ______________白白の屋    

             

            題目地址:

            http://acm.hdu.edu.cn/showproblem.php?pid=1512

            題目描述 :

            代碼
            Monkey King

            Time Limit: 
            10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
            Total Submission(s): 
            914    Accepted Submission(s): 426


            Problem Description
            Once 
            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 
            is10 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.
             

            Input
            There 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.

             

            Output
            For 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
            5
            20
            16
            10
            10
            4
            5
            2 3
            3 4
            3 5
            4 5
            1 5
             

            Sample Output
            8
            5
            5
            -1
            10
             

             

             

            題目分析:

            /*
            Mail to   : miyubai@gamil.com
            My Blog   : www.baiyun.me
            Link      : http://www.cnblogs.com/MiYu  || http://www.shnenglu.com/MiYu
            Author By : MiYu
            Test      : 1
            Complier  : g++ mingw32-3.4.2
            Program   : HDU_1512
            Doc Name  : Monkey King
                
                
            題目意思: 

            有N只猴子, 每只都有一個力量值. 開始的時候互不認識, 它們之間會發(fā)生M次斗爭. 每次發(fā)生a, b的斗爭時, a, b都會從各自的朋友圈里拉出一個最強的, 之后兩只猴子打, 打完后這兩只猴子的力量值各減半. 并且打完后, 兩只猴子的朋友圈的所有人都互相認識(也就是不會再打).

            你的任務就是對于每個斗爭, 若a, b是朋友, 那么輸出-1, 否則輸出打完后它們的朋友圈的最強猴子的力量值.

             使用 普通 優(yōu)先隊列的話 估計會超時, 因為數(shù)據(jù)量很大 100000 ! !, 等下有空試試看. 

            對于每一個節(jié)點, 定義dis 表示X節(jié)點到最右邊的空節(jié)點的距離的最小值

            對于每個節(jié)點X, 要求X的左兒子的dis >= 右兒子的dis, 那么容易發(fā)現(xiàn), 對于N個節(jié)點的左偏樹, 其右兒子最多只有l(wèi)ogN個節(jié)點.

            合并操作就是讓復雜度落在右兒子上, 從而達到logN的合并復雜度.

            首先對于兩個堆, 若其中一個為空, 返回另一個.

            否則(這里以大根堆為例), a指向堆頂較大的堆, b指向另一個. 讓a的右兒子和b合并, 合并后的子樹作為a的右兒子.

            接下來, 檢查a的兩個兒子是否滿足dis, 不滿足就交換兩個兒子.

            最后, 更新a的dis.

            這樣就容易實現(xiàn)堆的其他操作 ( 比如插入, 刪除頂?shù)?).

            另外 還需要用到 并查集.    
                
                
            */
            //#pragma warning( disable:4789 )
            #include <iostream>
            #include <fstream>
            #include <sstream>
            #include <algorithm>
            #include <string>
            #include <set>
            #include <map>
            #include <utility>
            #include <queue>
            #include <stack>
            #include <list>
            #include <vector>
            #include <cstdio>
            #include <cstdlib>
            #include <cstring>
            #include <cmath>
            #include <ctime>
            using namespace std;
            const int MM = 100010;
            struct left {
                    int l,r,dis,val,dad;
            } heap[MM];

            int N, M;

            inline int max ( const int &a, const int &b) {
                   return a > b ? a : b;
            }

            inline int find ( int &x ) {
                return heap[x].dad == x ? x : heap[x].dad = find ( heap[x].dad );
            }

            inline void swap(int &a, int &b) {
                 a ^= b ^= a ^= b;
            }

            inline int merge ( int x, int y ) {
                if ( x == 0 ) return y;
                if ( y == 0 ) return x;
                if ( heap[y].val > heap[x].val ) swap ( x, y );    
                heap[x].r = merge ( heap[x].r, y );
                heap[heap[x].r].dad = x;
                if ( heap[ heap[x].l ].dis < heap[ heap[x].r ].dis ) 
                     swap ( heap[x].l, heap[x].r );
                if ( heap[x].r == 0 ) heap[x].dis = 0;
                else heap[x].dis = heap[ heap[x].r ].dis + 1;
                return x;
            }

            inline int push ( int x, int y ) {
                   return merge ( x, y );       
            }

            inline int pop ( int &x ) {
                   int l = heap[x].l; 
                   int r = heap[x].r; 
                   heap[l].dad = l;
                   heap[r].dad = r;
                   heap[x].l = heap[x].r = heap[x].dis = 0;   
                   return merge ( l, r );  
            }

            inline bool scan_d(int &num) {
                    char in;bool IsN=false;
                    in=getchar();
                    if(in==EOF) return false;
                    while(in!='-'&&(in<'0'||in>'9')) in=getchar();
                    if(in=='-'){ IsN=true;num=0;}
                    else num=in-'0';
                    while(in=getchar(),in>='0'&&in<='9'){
                            num*=10,num+=in-'0';
                    }
                    if(IsN) num=-num;
                    return true;
            }

            int main() {
                while ( scan_d ( N ) ) {
                     for ( int i = 1; i <= N; ++ i ) {
                          scan_d ( heap[i].val );
                          heap[i].l = heap[i].r = heap[i].dis = 0;
                          heap[i].dad = i;    
                     }
                     scan_d ( M );
                     int a, b, x, y;
                     while ( M -- ) {
                            scan_d (a); scan_d (b);
                            x = find ( a );
                            y = find ( b ); 
                            if ( x == y ) {
                                puts ( "-1" );     
                            } else {
                                heap[x].val /= 2;
                                int xx = push ( pop ( x ), x );  
                                heap[y].val /= 2;
                                int yy = push ( pop ( y ), y );  
                                
                                printf ( "%d\n", heap[ merge ( xx, yy ) ].val );      
                            }    
                     } 
                }
                return 0;
            }


             

             

             

            久久国产亚洲高清观看| 久久久久久久精品成人热色戒| 久久水蜜桃亚洲av无码精品麻豆| 无遮挡粉嫩小泬久久久久久久| 青青青伊人色综合久久| 久久久久无码专区亚洲av| 久久精品国产2020| 亚洲一区中文字幕久久| 中文精品99久久国产 | 色综合久久无码五十路人妻| 国产高潮国产高潮久久久| 欧美亚洲另类久久综合婷婷| 久久国产精品99精品国产| 狠狠综合久久综合中文88| 欧美噜噜久久久XXX| 伊人色综合九久久天天蜜桃| 99久久国产亚洲高清观看2024| 国产精品99久久久精品无码| 久久久WWW成人| 亚洲国产成人久久综合碰碰动漫3d| 久久免费视频6| 国产免费久久久久久无码| 伊人久久大香线蕉综合5g| 亚洲嫩草影院久久精品| 国产精品久久亚洲不卡动漫| 久久婷婷五月综合97色| 亚洲精品无码久久久影院相关影片| 久久这里有精品视频| 精品久久久久一区二区三区| 久久精品中文字幕久久| 久久av无码专区亚洲av桃花岛| 一本综合久久国产二区| 久久久国产99久久国产一| 婷婷久久综合九色综合绿巨人| 狠狠色伊人久久精品综合网| 91精品观看91久久久久久 | 少妇久久久久久久久久| 久久AV无码精品人妻糸列| 伊人久久大香线蕉av不卡| 亚洲国产另类久久久精品黑人 | 一本大道加勒比久久综合|