• <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://m.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;
            }


             

             

             

            久久激情五月丁香伊人| 99精品久久精品| 青青草原综合久久大伊人| 亚洲欧美日韩中文久久 | 2022年国产精品久久久久 | 久久青青草原亚洲av无码app| 精品国产乱码久久久久久郑州公司 | 很黄很污的网站久久mimi色| 中文字幕精品久久| 久久国产精品一区二区| 漂亮人妻被中出中文字幕久久| 久久超乳爆乳中文字幕| 久久久久久A亚洲欧洲AV冫| 久久婷婷五月综合色高清 | 狠狠久久综合| 高清免费久久午夜精品| 久久精品国产男包| 国产精品免费看久久久香蕉| 无码国产69精品久久久久网站| 国产成人无码精品久久久免费| 久久夜色精品国产噜噜噜亚洲AV| 人妻少妇精品久久| 久久成人国产精品一区二区| 97久久精品人妻人人搡人人玩| 久久久久久久久久久| 亚洲精品成人网久久久久久| 国产精品热久久无码av| 久久美女网站免费| 日韩人妻无码精品久久久不卡| 亚洲婷婷国产精品电影人久久| 久久97久久97精品免视看| 久久精品国产只有精品2020| 久久精品无码专区免费东京热| 久久人人添人人爽添人人片牛牛| 一级做a爰片久久毛片看看| 久久久免费观成人影院| 久久久久亚洲AV成人网人人软件| 日韩欧美亚洲综合久久影院d3| 国产精品久久午夜夜伦鲁鲁| 国产精品免费看久久久| 精品国产一区二区三区久久|