[HDU 3031] To Be or Not to Be 斜堆模板題

To Be Or Not To Be

Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Problem Description

That’s a question. Now Happy (Xi Yangyang) has been caught by Wolffy (Hui Tailang). As Wolffy is busy preparing the big meal, a good idea comes to Happy. He proposes a game that only Wolffy had won, he can eat Happy. Wolffy always believes he is the cleverest one, so they reach a consensus. And they both agree with Wolnie (Hong Tailang) when the referee. A theater will be beat to die by Wolnie’s pan.

The game is defined as follow.

There are multiple test cases.

In each case there are R (R < 10) rounds of the game, R is an odd number to guarantee that there must be a winner in the end.

In each round: There is a pile of n (10 <= n <= 200) Special-cards and m (1 <= m <= 100) piles of Point-card on the table. The Point-card piles are ordered from 1 to m. Wolffy and Happy take turns to get one card from the top of Special-cards pile. Wolffy always takes first in the game. When all the Special-cards have been taken, the round is over and the one with more cards in the hands gains one point. If there is a tie, Wolffy gains one point.(Wolffty and Happy both have 0 point before the game).

There are 5 kinds of Special-cards besides the Point-card in the game.

0) Point-card: a card with a point X (1 <= X <= 2000000).

1) Challenge-card: no matter who takes this card, they both take one card with the maximum point from their own hands. After a comparison, if Happy’s card has a larger point, He takes all the Wolffy’s in-hands cards, vice versa; If there is a tie no more operation.

2) Loss-card: the one who takes this card, He must throw a card with the maximum point.

3) Add-card: a card with P point, the one who gets this card will make the card with maximum point P point larger, i.e. if a Point-card with X point is the maximum, its point will change to X + P. An Add-card can only work on one Point-card.

4) Exchange-card: a card with Q point. The one who gets this card must change one maximum-point card’s point to Q.

5) Take-card: a card with a integer K, indicates one can get the all the cards of Kth Point-card pile. In one round no two Take-card have the same K.

You can assume that when one gets the Loss-card, Add-card, Exchange-card, He has at least one card in the hands, when one gets a Challenge-card, they both have at least one card in the hands.

Input

For each test case, the first line of input is an integer R, indicates the number of rounds:

Line 2: two integers n indicates the number of Special-cards, m indicates the number of Point-card piles.

Line 3: a line of m integers. The ith number Pi (1 <= Pi <= 10000)indicates the number cards of ith Point-card pile.

For the next m lines, ith line contains Pi numbers indicate every Point-card’s point of ith Point-card pile.

The next n lines, in each line, there are five kinds of input, indicate Special-cards by the order of “from top to bottom”.

1) T K: indicates one gets a Take-card, and He can get Kth Point-card pile(1 <= K <= m).

2) C: indicates one gets a Challenge card.

3) L: indicates one gets a Loss card.

4) A P: indicates one gets an Add card with P point (1 <= P <= 30).

5) E Q: indicates one gets an Exchange card with Q point (1 <= Q <= 2000000).

Output

For each round you should print A:B in a line. A indicate the number of left cards of Wolffy, B indicates the number of left cards of Happy. At the end of game, if Wolffy gains more points, print “Hahaha…I win!!”, else print “I will be back!!”.

Sample Input

3
5 3
3 3 3
10 11 2
7 4 12
4 2 9
T 1
T 2
A 7
T 3
C
6 3
2 2 2
1 4
5 2
4 2
T 2
T 1
L
A 2
T 3
C
5 3
2 2 2
1 3
4 2
5 2
T 2
T 1
E 3
A 1
L

Sample Output

9:0
0:5
1:2
I will be back!!

斜堆模板題, 和左偏差不多
(允許我懶一發。。)

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
const int MAXN = 5000000;
namespace mheap {
    const int MAXD = MAXN;
    struct Node {
        int w, l, r, fa;
    } d[MAXD];
    int tot = 0;
    inline int newNode (int val = 0) {
        memset(d+(++tot), 0, sizeof d[0]);
        d[tot].w = val;
        return tot;
    }
    inline void clear() {
        tot = 0;
    }

    inline int merge(int a, int b) {
        if(a == 0 || b == 0) return a+b;
        if(d[a].w < d[b].w) std :: swap(a, b);
        d[a].l = merge(d[a].l, b);
        std :: swap(d[a].l, d[a].r);
        return a;
    }


    int que[MAXD];
    int build(int * l, int * r) {
        int lef = 0, rig = -1;
        while(l+(++rig) != r)
            que[rig] = newNode(l[rig]);
        --rig;
        while(lef != rig) {
            int a = que[lef++];
            lef %= MAXD;
            int b = que[lef++];
            lef %= MAXD;
            ++rig; rig%=MAXD;
            que[rig] = merge(a, b);
            //printf("mg:%d %d\n", a, b);
        }
        return que[rig];
    }

    inline int pop(int u) {
        return merge(d[u].l, d[u].r);
    }
    inline int & val(int u) {
        return d[u].w;
    }

    int size(int u) {
        if(!u) return 0;
        return size(d[u].l) + size(d[u].r) + 1;
    }

}

int sz[MAXN];
int buf[MAXN];
int piles[MAXN];
int player[2];
int main () {
    int r;
    while(~scanf("%d", &r)) {
        mheap :: clear();
        int cnt1 = 0, cnt2 = 0;

        for(int t = 0; t<r; t++) {
            player[0] = player[1] = 0;
            int n, m;
            scanf("%d%d", &n, &m);
            for(int i = 1; i<=m; i++)
                scanf("%d", &sz[i]);
            for(int i = 1; i<=m; i++) {
                for(int j = 1; j<=sz[i]; j++)
                    scanf("%d", &buf[j]);
                piles[i] = mheap :: build(buf+1, buf+sz[i]+1);
            }
            char ord[5];
            int arg;
            for(int i = 0; i<n; i++) {
                int & p1 = player[i&1], & p2 = player[!(i&1)];
                scanf("%s", ord);
                if(ord[0] == 'T') {
                    scanf("%d", &arg);
                    p1 = mheap :: merge(piles[arg], p1);
                }
                else if(ord[0] == 'C') {
                    //printf("p1:%d p2:%d\n", mheap :: val(p1), mheap :: val(p2));
                    if(mheap :: val(player[1]) > mheap :: val(player[0]))
                        player[1] = mheap :: merge(player[1], player[0]), player[0] = 0;
                    else if(mheap :: val(player[1]) < mheap :: val(player[0]))
                        player[0] = mheap :: merge(player[1], player[0]), player[1] = 0;
                }
                else if(ord[0] == 'L') 
                    p1 = mheap :: pop(p1);
                else if(ord[0] == 'A') {
                    scanf("%d", &arg);
                    mheap :: val(p1) += arg;
                }
                else if(ord[0] == 'E') {
                    scanf("%d", &arg);
                    p1 = mheap :: pop(p1);
                    p1 = mheap :: merge(p1, mheap :: newNode(arg));
                }
            }
            int ans1 = mheap :: size(player[0]);
            int ans2 = mheap :: size(player[1]);
            printf("%d:%d\n", ans1, ans2);
            if(ans1 > ans2) cnt1 ++;
            else cnt2 ++;
        }
        if(cnt1 > cnt2) puts("Hahaha...I win!!");
        else puts("I will be back!!");
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章