题目链接:http://poj.org/problem?id=2528
题目大意:
给出n个海报的左端,右端,按照顺序贴上海报
求贴完后可以看到多少海报?
方法:
先将海报数据离散化,然后线段树查询
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; const int maxn = 10010; struct node { int l, r; } Poster[maxn]; int Section[maxn*2]; int Hash[maxn*1000]; struct Tree { int l, r; bool flag; } ans[maxn*10]; void Build(int l, int r, int rt) { ans[rt].l = l, ans[rt].r = r; ans[rt].flag = false; if(l == r) return; int mid = (l + r) >> 1; Build(l, mid, rt<<1); Build(mid+1, r, rt<<1|1); } bool Judge(int l, int r, int rt) { if(ans[rt].flag) return false; if(l == ans[rt].l && r == ans[rt].r) { ans[rt].flag = true; return true; } bool Flag; int mid = (ans[rt].l + ans[rt].r) >> 1; if(r <= mid) Flag = Judge(l, r, rt<<1); else if(l > mid) Flag = Judge(l, r, rt<<1|1); else { bool flag1 = Judge(l, mid, rt<<1); bool flag2 = Judge(mid+1, r, rt<<1|1); Flag = (flag1 || flag2); } if(ans[rt<<1].flag && ans[rt<<1|1].flag) ans[rt].flag = true; return Flag; } int main() { int T, n; scanf("%d",&T); while(T-- && scanf("%d",&n)) { int Count = 0; for(int i=0; i<n; i++) { scanf("%d%d",&Poster[i].l, &Poster[i].r); Section[Count++] = Poster[i].l, Section[Count++] = Poster[i].r; } sort(Section, Section+Count); Count = unique(Section, Section+Count) - Section; for(int i=0; i<Count; i++) Hash[Section[i]] = i; // printf("%d\n",Count); Build(0, Count-1, 1); int ant = 0; for(int i=n-1; i>=0; i--) if(Judge(Hash[Poster[i].l], Hash[Poster[i].r], 1)) ant++; printf("%d\n",ant); } return 0; }