HDU1199 動態線段樹 // 離散化

附動態線段樹AC代碼php

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

由於昨天作了一道動態線段樹的緣故,今天遇到了這題沒有限制範圍的題就天然而然想到了動態線段樹的解法,寫完看題解發現原來只要離散化就行了(幹。。),總結了一下這題和昨天hdu5367的區別在於,雖然都是兩題範圍超級大的線段樹,可是昨天的強制要求在線求解,只能選擇空間複雜度更大一些的動態線段樹來求解,而今天的這題能夠選擇離線操做,於是能夠採用先讀入全部輸入,離散化以後建樹的方法來操做。下次遇到這樣的題仍是應當優先考慮離散化。git

 

在一個所有塗黑色的條子上塗上一些白色或黑色的片斷,問最大白色片斷。spa

僅僅從線段樹維護節點的角度上來看很簡單,維護最大白色片斷,左邊最大白色片斷,右邊最大白色片斷就行了。code

因爲條子的長度長達1-INT_MAX;blog

採用離散化,或者像我同樣失了智去用動態線段樹的方法,也能ACget

#include <map> #include <set> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional>
#define For(i, x, y) for(int i=x; i<=y; i++)  
#define _For(i, x, y) for(int i=x; i>=y; i--)
#define Mem(f, x) memset(f, x, sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);  
#define CLR(u) for(int i = 0; i <= N ; i ++) u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
using namespace std; typedef vector<int> VI; const double eps = 1e-9; const int maxn = 2010; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; inline int read() { int now=0;register char c=getchar(); for(;!isdigit(c);c=getchar()); for(;isdigit(c);now=now*10+c-'0',c=getchar()); return now; } int N,M; struct Tree{ LL sum; //最大連續 
    LL lsum;   //左連續 
    LL rsum;   //右連續 
    int lt; int rt; int lazy; void init(){ lsum = rsum = sum = lt = rt = 0; lazy = -1; } }tree[maxn * 60]; int tot; void check(int &t){ if(t) return; t = ++tot; tree[t].init(); } void add(int &t,LL L,LL R,int v){ if(v){ tree[t].sum = tree[t].lsum = tree[t].rsum = R - L + 1; }else{ tree[t].sum = tree[t].lsum = tree[t].rsum = 0; } tree[t].lazy = v; } void Pushdown(int& t,LL L,LL R){ if(tree[t].lazy == -1) return; int &lt = tree[t].lt; int &rt = tree[t].rt; LL M = (L + R) >> 1; check(lt); check(rt); add(lt,L,M,tree[t].lazy); add(rt,M + 1,R,tree[t].lazy); tree[t].lazy = -1; } void Pushup(int t,LL L,LL R){ int &ls = tree[t].lt; int &rs = tree[t].rt; LL M = (L + R) >> 1; check(ls); check(rs); tree[t].sum = max(tree[ls].sum,tree[rs].sum); tree[t].sum = max(tree[t].sum,tree[ls].rsum + tree[rs].lsum); tree[t].lsum = tree[ls].lsum; if(tree[ls].lsum == M - L + 1){ tree[t].lsum = tree[ls].lsum + tree[rs].lsum; } tree[t].rsum = tree[rs].rsum; if(tree[rs].rsum == R - M){ tree[t].rsum = tree[rs].rsum + tree[ls].rsum; } } void update(int &t,int q1,int q2,LL L,LL R,int v){ check(t); if(q1 <= L && R <= q2){ add(t,L,R,v); return; } Pushdown(t,L,R); LL m = (L + R) >> 1; if(q1 <= m) update(tree[t].lt,q1,q2,L,m,v); if(q2 > m) update(tree[t].rt,q1,q2,m + 1,R,v); Pushup(t,L,R); } LL Left,Right; void query(int t,LL L,LL R){ if(L == R){ Left = L; Right = R; return; } check(tree[t].lt); check(tree[t].rt); int ls = tree[t].lt; int rs = tree[t].rt; LL M = (L + R) >> 1; if(tree[ls].sum == tree[t].sum) query(ls,L,M); else if(tree[rs].sum == tree[t].sum) query(rs,M + 1,R); else{ Left = M - tree[ls].rsum + 1; Right = M + tree[rs].lsum; return; } } int main() { while(~Sca(N)){ LL L = 1; LL R = 2147483647; tot = 0; int root = 0; update(root,L,R,L,R,0); For(i,1,N){ LL l,r; char op[3]; scanf("%lld%lld%s",&l,&r,&op); if(op[0] == 'w'){ update(root,l,r,L,R,1); }else{ update(root,l,r,L,R,0); } } if(!tree[root].sum){ puts("Oh, my god"); continue; } query(root,L,R); printf("%lld %lld\n",Left,Right); } return 0; } 
相關文章
相關標籤/搜索