hdoj 5200 Trees 【思维】

来源:互联网 发布:软件售后前途 编辑:程序博客网 时间:2024/04/25 07:35

题目链接:hdoj 5200 Trees

题意:给你n棵树以及每棵树的高度,有Q次查询,每次给定一个高度v,表示砍掉高度<=v的所有树,问剩余的块数。

块的定义:
一、临近的树在同一个块;
二、若xy在同一个块,xz在同一个块,那么zy也在同一个块。

思路:我们先按高度升序sort,这样处理第i棵树时,它的状态来源于第i1棵树,影响它的只有位置临近它的两棵树(边界只有一棵树)。那么我们考虑位置是id的树——假如id1id+1被砍了,显然id本身就为一个独立的块,砍了后就没了;若id1id+1没有被砍,id就划分出了一个块;若只有一棵被砍,则状态直接转移,不会改变。

AC代码:

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <algorithm>#include <vector>#include <queue>#include <map>#include <stack>#define PI acos(-1.0)#define CLR(a, b) memset(a, (b), sizeof(a))#define fi first#define se second#define ll o<<1#define rr o<<1|1using namespace std;typedef long long LL;typedef pair<int, int> pii;const int MAXN = 5*1e4+10;const int INF = 0x3f3f3f3f;const int MOD = 1e9 + 7;void getmax(int &a, int b) {a = max(a, b); }void getmin(int &a, int b) {a = min(a, b); }void add(LL &x, LL y) { x += y; x %= MOD; }bool cmp(pii a, pii b) {    return a.fi != b.fi ? a.fi < b.fi : a.se < b.se;}pii a[MAXN];bool cut[MAXN];int ans[MAXN];int main(){    int N, Q;    while(scanf("%d%d", &N, &Q) != EOF)    {        for(int i = 0; i < N; i++) {            scanf("%d", &a[i].fi);            a[i].se = i;            cut[i] = false;        }        sort(a, a+N, cmp); int cnt = 1;        for(int i = 0; i < N; i++)        {            int id = a[i].se;            int cutnum;            if(id == 0) {                if(cut[id+1]) {                    cnt--;                }                else {                    //cnt++;                }            }            else if(id == N-1) {                if(cut[id-1]) {                    cnt--;                }                else {                    //cnt++;                }            }            else {                if(cut[id+1] && cut[id-1]) {                    cnt--;                }                else if(!cut[id-1] && !cut[id+1]) {                    cnt++;                }            }            cut[id] = true; ans[id] = cnt;            //cout << id << " " << ans[id] << endl;        }        while(Q--)        {            int v; scanf("%d", &v);            int p = lower_bound(a, a+N, pii(v+1, -1)) - a;            if(p == 0) cout << 1 << endl;            else {                int id = a[p-1].se;                cout << ans[id] << endl;            }        }    }    return 0;}
0 0