1. 程式人生 > >HDU5575 Discover Water Tank 2015上海現場賽D題 (樹形dp,並查集,左偏樹)

HDU5575 Discover Water Tank 2015上海現場賽D題 (樹形dp,並查集,左偏樹)

題目大意:
有一個1維的長度為N,高度無限的水櫃,現在要用N-1個擋板將其分為N個長度為1的小格,然後向水櫃中注水,水可以低於擋板也可以以溢位去(這樣就要與旁邊格子的水位相同),現在有M次探測,探測i,y,k為查詢第i個格子高度y+0.5處是否有水,k=1表示有水,k=0表示沒有水,這M次探測不保證結果正確,現求結果正確個數的最大可能值。

思路:
這道題可以用類似樹形dp的方法求解,依照分隔擋板由低到高的順序將相鄰的水櫃合併,視為一個水櫃,在合併前分別對兩個水櫃加水到剛好溢位,而對超出此水位的探測暫不處理,求出區域性最優解(不溢位最優解f和溢位最優解g),並將各自未處理的探測合併為一個集合。不斷進行此過程最後求出整個水櫃的最優解。

主要操作為合併和注水,對每個水櫃維護下列值:
注水高度h,不溢位最優解f,溢位最優解g,未處理探測集合E

以樣例1為例說明處理方法
這裡寫圖片描述
初狀態
水櫃1:h=0,f=0,g=0,E={<1,3,1>}
水櫃2:h=0,f=0,g=0,E={<2,1,0>,<2,2,0>}
水櫃3:h=0,f=0,g=0,E={<3,3,1>}

先將擋板由低到高排序
於是首先合併水櫃1和水櫃2,合併前先分別對兩個水櫃注水到擋板的高度3,
水櫃1:h=3,f=0,g=0,E={<1,3,1>}
水櫃2:h=3,f=2,g=0,E={}
合併後水櫃1~2:h=3,f=2,g=0,E={<1,3,1>}

然後合併水櫃1~2和水櫃3,合併前先分別對兩個水櫃注水到擋板的高度4,
水櫃1~2:h=4,f=2,g=1,E={}
水櫃3:h=4,f=1,g=1,E={}
合併後水櫃1~3:h=4,f=3,g=2,E={}

最後注水到最大值(比如1e9+5)
水櫃1~3:h=4,f=3,g=2,E={}

於是得到結果為3

可以用並查集維護合併過程,用左斜樹(或其它可合併優先佇列)合併未處理的探測集合E,這樣每次合併的複雜度為O(logN+logM),N次合併的總複雜度為O(NlogN+NlogM)

程式碼:
Problem : 5575 ( Discover Water Tank ) Judge Status : Accepted
RunId : 15797292 Language : G++ Author : qsqx
3213MS 9832K

#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <map>
#include <stack>
#include <vector>
#include <memory.h>
#include <set>
#include <string.h>
#include <list>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <queue>
#define ll long long
#define forn(i,n) for(int i=0;i<n;++i)
#define rep(i,n) for(int i=1;i<=n;++i)
#define repc(i,l,r) for(int i=l;i<=r;++i)
#define mp(a,b) make_pair(a,b)
#define llf long double
#define pii pair<int,int>
using namespace std; 
int l[200005];
int r[200005];
pii query[200005];//
int dist[200005];
int dsu[100005];
pii stk[200005];//
int merge(int a, int b) {
    if (!a)return b;
    else if (!b)return a;
    if (query[a].first > query[b].first)swap(a, b);
    r[a] = merge(r[a], b);
    if (dist[r[a]] > dist[l[a]])swap(l[a], r[a]);
    if (!r[a]) dist[a] = 0;
    else dist[a] = dist[r[a]] + 1;
    return a;
}
struct Node {
    int qu, h;
    int f, g;
    void get(int hgt) {
        int nw = 0;
        int mx = 0;
        int fmr = -1;
        int tol = 0;
        int nf;
        while (qu&&query[qu].first<hgt) {
            stk[tol++] = query[qu];
            if (query[qu].second == 0) ++nw;
            qu = merge(l[qu], r[qu]);
        }
        nf = nw;
        forn(i, tol) {
            if (stk[i].first != fmr) {
                mx = max(mx, nw);
                fmr = stk[i].first;
            }
            if (stk[i].second)++nw;
            else --nw;
        }
        mx = max(mx, nw);
        f = max(f+nf, g + mx);//not overflow
        g += nw;
        h = hgt;
    }
}nds[100005];

int getgp(int u) {
    return dsu[u] = (dsu[u] != u ? getgp(dsu[u]) : u);
}
void mrg(int u, int v, int h) {
    u = getgp(u);
    v = getgp(v);
    if (nds[u].h < h) {
        nds[u].get(h);
    }
    if (nds[v].h < h) {
        nds[v].get(h);
    }
    dsu[v] = u;
    nds[u].qu = merge(nds[u].qu, nds[v].qu);
    nds[u].f += nds[v].f;
    nds[u].g += nds[v].g;
}
int n, m;
pii board[100005];//
void solve() {
    memset(l, 0, sizeof(l));
    memset(r, 0, sizeof(r));
    memset(dist, 0, sizeof(dist));
    memset(nds, 0, sizeof(nds));
    memset(board, 0, sizeof(board));
    memset(query, 0, sizeof(query));
    cin >> n >> m;
    rep(i, n)dsu[i] = i;
    rep(i, n - 1) {
        scanf("%d", &board[i].first);
        board[i].second = i;
    }
    sort(board + 1, board + n);

    int S = 0;
    rep(i, m) {
        int x;
        scanf("%d%d%d", &x, &query[i].first, &query[i].second);
        if (query[i].second) ++S;
        nds[x].qu = merge(nds[x].qu, i);
    }
    rep(i, n - 1) {
        mrg(board[i].second, board[i].second + 1, board[i].first);
    }
    int rt = getgp(1);
    nds[rt].get(1e9 + 100);
    cout << nds[rt].f << endl;
}
int main(){
    //freopen("abc.txt", "r", stdin);
    int T;
    cin >> T;
    rep(t, T) {
        printf("Case #%d: ", t);
        solve();
    }
    return 0;
}

相關推薦

HDU5575 Discover Water Tank 2015上海現場D 樹形dp

題目大意: 有一個1維的長度為N,高度無限的水櫃,現在要用N-1個擋板將其分為N個長度為1的小格,然後向水櫃中注水,水可以低於擋板也可以以溢位去(這樣就要與旁邊格子的水位相同),現在有M次探測,探測i,y,k為查詢第i個格子高度y+0.5處是否有水,k=1表示

ZOJ-4061 Magic Multiplication 2018年青島區域現場D思維 + 暴力構造

題目連結:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4061 題目大意:題目定義一個運算子對於數A和數B的運演算法則為 , 表示數A的第 i 位數,表示數B的第 j 位數,現在令字串,這裡的加法為字串連

ZOJ3822 ACM-ICPC 2014 亞洲區域牡丹江賽區現場DDomination 概率DP

Domination Time Limit: 8 Seconds      Memory Limit: 131072 KB      Special Judge Edward is the headmaster of Marjar University. He is ent

2015上海現場 HDU 5573

這是一道在克隆賽碰到的題,當時看題隊友以為是樹形dp或者是暴搜,想了一下都沒有思路,其實是一道 " 思維+二進位制 "。   題目連結:傳送門   題意:給你一棵有K層的滿二叉樹,讓你從根節點開始走(根節點為1),經過K個節點(包括根節點),走到葉子節點

LCM Walk【2015上海現場】【推理】

題意:有已知的[ex, ey],求可以由[sx+lcm(sx, sy), sy]或者[sx, sy+lcm(sx, sy)]得到,求這樣的[sx, sy]的數目,當然,[ex, ey]也算是一組。 一道推理題,顯而易見,知[ex, ey]那我們得把關係聯絡起來,[sx+sx

2018年 ACM/ICPC亞洲區域 青島賽區現場 FZOJ 4063 思維

DreamGrid, the king of Gridland, is making a knight tournament. There are  knights, numbered from 1 to , participating in the tournamen

2018ACM-ICPC南京現場D Country Meow

2018ACM-ICPC南京現場賽D題-Country Meow Problem D. Country Meow Input file: standard input Output file: standard output In the 24th century, there is a country so

ZOJ 3822 Domination 概率DP 2014年ACM_ICPC亞洲區域牡丹江現場D

題目大意: 就是現在有一個N*M的棋盤(1 <= N, M <= 50)每次在上面的空位置隨機選一個放一個棋子, 問使得所有行和所有列上都有棋子放置, 放置的棋子的數目期望 大致思路: 這題同步賽的時候沒感覺, 現在做發現就是一個水題, 當時還是太弱了...

COCI2014/2015 Contest#1 D MAFIJA樹形DP/貪心

題意 給定一個 n n n 個節點的圖,每個點有且僅有一條出邊,選取最多的點使得沒有邊連線相鄰兩個

第二次周DHDU-1013

問題連結:https://vjudge.net/problem/HDU-1013 問題簡述:求數根。(個位的累加) Get:有兩種方法: 1.硬剛(求得每個位上的數,再相加,再判斷) AC程式碼: #include <string> #include <io

2015藍橋杯決賽 關聯賬戶(水)

題目: 標題:關聯賬戶 為增大反腐力度,某地警方專門支隊,對若干銀行賬戶展開調查。 如果兩個賬戶間發生過轉賬,則認為有關聯。如果a,b間有關聯, b,c間有關聯,則認為a,c間也有關

2015 ACM/ICPC 北京區域 現場 D—Kejin Game【網路流】

題意: 題意:給一顆有向樹,技能獲得的前提是他的前置技能都獲得了,作為一個玩家,你有特權: 1.直接花費一定數量的錢獲得某個技能。 2.花費一定數量的錢將一個技能的某一個前置關係取消,即將前置技能到該技能的邊消除(不需要獲得前置技能)。 如果正常學習技能的話

HDU 5575 Discover Water Tank +

不妨假定初始答案為所有的無水詢問,因為這樣一定沒有衝突。 然後列舉有水詢問、水位線到這裡時,答案能否更優。 若水位線達到某一高度,則可能淹沒旁邊的水箱,那麼實際就變成了一個大水箱,所以考慮用並查集來優化,為保證合併順序正確,先對有水詢問按水位高度排序。 下面思考更新答案,樸

HDU 5581 Infinity Point Sets ACM/ICPC 2015 上海區域 I 計算幾何+組合計數

2015年上海區域賽的題目,這道題還是比較有趣的,反正我是WA哭了。。 題目在HDU上也有,連結: 題目的意思是,給出二維空間裡n個點的座標,求有多少個不同的子點集不是無限點集。無限點集的定義是,將點集中的點兩兩相連,線段產生的交點加入點集中,繼續上面的操作,如果操作能

hdu 5538 House Building長春現場——水

onos white ng- ron number ots 1.7 mage time 題目鏈接:acm.hdu.edu.cn/showproblem.php?pid=5538 House Building Time Limit: 2000/1000

2017 ICPC 西安站現場 A.XOR 線段+線性基

getchar tput 線性 calculate ext following case all pri XORConsider an array A with n elements. Each of its element is A[i] (1 ≤ i ≤ n). Th

HDU 5117 2014ICPC北京現場 F - Fluorescent (狀壓DP)

題目連結 有n個燈和m個開關,每個開關控制一些燈,顯然開關的狀態有2^m種。設亮著的燈的數目為x,求所有狀態下x^3之和。 n,m <= 50顯然不能直接計算每種x進行dp的。考慮直接計算x^3。 x^3 = (x1 + x2 + ... + xn)* (x1 + x2 + ...

HDU 5130 & 5134 2014ICPC廣州現場 D & H (計算幾何)

2014GZ - D  & 2014GZ - H D - Signal Interference 給定一個多邊形及其內部的點A,並給出另一個點B,求多邊形內部到B距離不超過到A距離的k倍的點集的面積。 經過推導可以得出來滿足距離關係的點集是一個圓,那麼就只需要

ACM-ICPC 2018 青島賽區現場 D. Magic Multiplication && ZOJ 4061 思維+構造

題目連結:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4061 題意:定義一個長度為 n 的序列 a1,a2,..,an 和長度為 m 的序列 b1,b2,..,bm 所構成的新序列 c 為 a1b1,a1b2,....,anbm

2018icpc青島現場 F(思維倍增塊交換

題目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4063 對於n的大小,對戰輪數有規律可循,k<(n&-n)方可分配方案,其餘Impossible. #include<cstdio>