Zoj 3511 线段树

我们需要维护一个区间和表示各个区间剩下多少个点,每次切一个多边形的时候先算一下被切下来的多边形有多少条边(多少个顶点),然后把这些顶点抹掉即可。

但是会出现一个问题,如果被切下来的多边形还要继续被切,怎么破? 因为切的顺序是无关的,所以先将所有切的操作排序,先处理切下来小块的,然后处理大块的,就可以避免这个问题了。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <queue>
#include <deque>
#include <bitset>
#include <list>
#include <cstdlib>
#include <climits>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <stack>
#include <sstream>
#include <numeric>
#include <fstream>
#include <functional>

using namespace std;

#define MP make_pair
#define PB push_back
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef pair<int,int> PII;
const int INF = INT_MAX / 3;
const double eps = 1e-8;
const LL LINF = 1e17;
const double DINF = 1e60;
const int maxn = 1e4 + 10;

int sum[maxn << 2],n,m;
PII Q[maxn];

void build(int rt,int l,int r) {
    int mid = (l + r) >> 1;
    if(l == r) sum[rt] = 1;
    else {
        build(lson); build(rson);
        sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
    }
}

void update(int rt,int l,int r,int ql,int qr) {
    if(ql <= l && qr >= r) sum[rt] = 0;
    else {
        int mid = (l + r) >> 1, lc = rt << 1, rc = rt << 1 | 1;
        if(sum[rt] == 0) {
            sum[lc] = sum[rc] = 0;
            return;
        }
        if(ql <= mid) update(lson,ql,qr);
        if(qr > mid) update(rson,ql,qr);
        sum[rt] = sum[lc] + sum[rc];
    }
}

int query(int rt,int l,int r,int ql,int qr) {
    if(ql <= l && qr >= r) return sum[rt];
    int mid = (l + r) >> 1,ret = 0;
    if(sum[rt] == 0) return 0;
    if(ql <= mid) ret += query(lson,ql,qr);
    if(qr > mid) ret += query(rson,ql,qr);
    return ret;
} 

bool cmp(const PII &a, const PII &b) {
    return abs(a.first - a.second) < abs(b.first - b.second);
}


int main() {
    while(scanf("%d%d",&n,&m) != EOF) {
        build(1,1,n);
        int ans = 0;
        for(int i = 0;i < m;i++) {
            scanf("%d%d",&Q[i].first,&Q[i].second);
        }
        sort(Q, Q + m, cmp);
        for(int i = 0;i < m;i++) {
            int l = Q[i].first, r = Q[i].second;
            if(l > r) swap(l,r);
            ans = max(query(1,1,n,l,r),ans);
            update(1,1,n,l + 1,r - 1);
        }
        ans = max(ans,query(1,1,n,1,n));
        printf("%d\n",ans);
    }
    return 0;
}

  

posted @ 2014-08-23 13:58  acm_roll  阅读(181)  评论(0编辑  收藏  举报