离散化+线段树简单例题

  POJ 2528

  求没有被完全覆盖的海报(不知道是不是这个意思)有多少张。注意题目一开始给的数字不是线段的端点而是线段。所以离散化的时候需要先处理,也就是把右端点+1.然后离散化,插入的时候应该插入线段,所以应该插入(left, right-1)。然后查询只需查询一次,标记即可。

  ZOJ 2301, HDU 1199

  做法是一样的,都是一维线段树,比较好处理。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <cmath>
#include <ctime>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <string>
#include <bitset>
#include <vector>
#include <deque>
#include <utility>
#include <list>
#include <sstream>
#include <iostream>
#include <fstream>
#include <functional>
#include <numeric>
#include <algorithm>


using namespace std;

//TEMPLATE_BY_LIKE
#define EP 1E-10
#define CLR(arr, v) memset(arr, v, sizeof(arr))
#define SQ(a)       ((a)*(a))
#define DEBUG(a)    printf("%s = %s\n", #a, toStr(a).c_str())
#define FOR(i,s,e)  for( int (i)=(s); (i) < (e) ; i++)
#define SIZE(X)     ((int)(X.size()))
#define LENGTH(X)   ((int)(X.length()))
#define two(X)      (1<<(X))
#define twoL(X)     (((int64)(1))<<(X))

typedef long long LL;
typedef unsigned long long uLL;
const   double PI = acos(-1.0);
int     toInt(string s)   {int r=0; istringstream sin(s); sin>>r; return r;}
LL      toInt64(string s) {LL r=0; istringstream sin(s); sin>>r; return r;}
double  toDouble(string s){double r=0; istringstream sin(s); sin>>r; return r;}
double  dist(double x1, double y1, double x2, double y2){return sqrt(SQ(x1-x2)+SQ(y1-y2));}
bool isUpperCase(char c){return c >= 'A' && c <= 'Z';}
bool isLowerCase(char c){return c >= 'a' && c <= 'z';}
bool isLetter(char c)   {return c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z';}
bool isDigit(char c)    {return c >= '0' && c <= '9';}
char toLowerCase(char c){return (isUpperCase(c))?(c + 32) : c;}
char toUpperCase(char c){return (isLowerCase(c))?(c - 32) : c;}

template<class T> inline T strTo(string s){istringstream is(s);T v;is>>v;return v;}
template<class T> inline string toStr(const T& v){ostringstream os;os<<v;return os.str();}
template<class T> inline int cMin(T& a, const T& b){return b<a?a=b,1:0;}
template<class T> inline int cMax(T& a, const T& b){return a<b?a=b,1:0;}
template<class T> inline int cBit(T n){return n?cBit(n&(n-1))+1:0;}
template<class T> inline T lowbit(T n){return (n^(n-1))&n;}
template<class T> inline T GCD(T a, T b)
  {if(a<0)return GCD(-a,b);if(b<0)return GCD(a,-b);return (b==0)?a:GCD(b,a%b);}
template<class T> inline T LCM(T a, T b)
  {if(a<0)return LCM(-a,b);if(b<0)return LCM(a,-b);return a*(b/gcd(a,b));}
//TEMPLATE_BY_LIKE

struct TNode{
    int l, r;
    int color;
    bool cover;
    TNode *left, *right;
};

TNode tree[50000];
int ncount;

void buildTree(TNode *root, int l, int r){

    root->l = l;
    root->r = r;
    root->cover = true;
    root->color = 1;

    if (l != r){
        ncount++;
        root->left = tree + ncount;
        ncount++;
        root->right = tree + ncount;
        buildTree(root->left, l, (l + r) / 2);
        buildTree(root->right, (l + r) / 2 + 1, r);
    }
}


void insert(TNode *root, int l, int r, int col){

    if (root->cover && root->color == col)
        return;

    if (root->l == l && root->r == r){
        root->cover = true;
        root->color = col;
        return;
    }

    if (root->cover){
        root->cover = false;
        root->left->cover = true;
        root->right->cover = true;
        root->left->color = root->color;
        root->right->color = root->color;
    }

    if (root->r != root->l){

        int mid = (root->l + root->r) / 2;

        if (mid < l)
            insert(root->right, l, r, col);
        else if (mid >= r)
            insert(root->left, l, r, col);
        else {
            insert(root->left, l, mid, col);
            insert(root->right, mid + 1, r, col);
        }
    }

}

bool vis[5000];

void query(TNode *root, int l, int r){

    if (root->cover){
        if (root->color == 2){
            for (int i = root->l; i <= root->r; i++)
                vis[i] = true;
        }
        return;
    }

    if (root->l - root->r){

        int mid = (root->l + root->r) / 2;

        if (mid < l)
            query(root->right, l, r);
        else if (mid >= r)
            query(root->left, l, r);
        else {
            query(root->left, l, mid);
            query(root->right, mid + 1, r);
        }
    }

}

map<int, int> ma;
struct node{
    int start, end, col;
};

node d[2100];
int p[5000], q[5000];

int main() {

    int n;
    while (~scanf("%d", &n)){

        int t = 0;
        ma.clear();

        for (int i = 0; i < n; i++) {
            char c[3];
            scanf("%d%d%s", &d[i].start, &d[i].end, c);

            d[i].end++;

            if (d[i].start > d[i].end){
                int t = d[i].start;
                d[i].start = d[i].end;
                d[i].end = t;
            }
            if (c[0] == 'w'){
                d[i].col = 2;
            }else d[i].col = 1;

            p[t++] = d[i].start;
            p[t++] = d[i].end;
        }

        sort(p, p + t);
        int k = 0;
        ma[p[0]] = ++k;
        q[k] = p[0];

        for (int i = 1; i < t; i++)
            if (p[i] != p[i - 1]) {
                ma[p[i]] = ++k;
                q[k] = p[i];
            }

        ncount = 0;
        buildTree(tree, 1, k);

        for (int i = 0; i < n; i++) {
            int a = ma[d[i].start], b = ma[d[i].end];
            insert(tree, a, b - 1, d[i].col);
        }

        CLR(vis, 0);
        query(tree, 1, k);

        int maxlen = -1, s = 1;
        int l1 = 0, l2 = 0;
        bool flag = false;

        for (int i = 1; i <= k; i++){
            if (!vis[i] && vis[i - 1]){
                if (maxlen < q[i] - 1 - q[s]){
                    maxlen = q[i] - 1 - q[s];
                    l1 = q[s];
                    l2 = q[i] - 1;
                    flag = true;
                }
            }
            if (vis[i] && !vis[i - 1])
                s = i;
        }
        if (maxlen < q[k] - q[s] && vis[k]){
            l1 = q[s];
            l2 = q[k];
            flag = true;
        }

        if(!flag)printf("Oh, my god\n");
        else
            printf("%d %d\n", l1, l2);
    }

    return 0;
}

 

posted @ 2011-11-13 16:41  like@neu  阅读(410)  评论(0编辑  收藏  举报