UVA12663 线段树+二分

来源:互联网 发布:unity3d卡牌游戏教程 编辑:程序博客网 时间:2024/06/05 05:31




分析:线段树模板+二分查找

读入每座桥的高度,然后排序。

m次洪水,每次二分查找在高度在区间【Bi-1,A】的桥的个数,然后区间更新。


代码如下:

#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>using namespace std;const int maxn = 100000;int n,m,k;int a,b;int h[maxn+10];struct node{    int lc,rc;    int add;    int sum;}tree[maxn*4+10];int ans;void pushdown(int root, int x){    if (tree[root].add){        tree[root<<1].sum += tree[root].add*(x-(x>>1));        tree[root<<1|1].sum += tree[root].add*(x>>1);        tree[root<<1].add += tree[root].add;        tree[root<<1|1].add += tree[root].add;        tree[root].add = 0;    }}void build(int root,int L, int R){    tree[root].lc = L;    tree[root].rc = R;    tree[root].add = 0;    tree[root].sum = 0;    if (L==R) return;    int mid = (L+R)>>1;    build(root<<1,L,mid);    build(root<<1|1,mid+1,R);}void update(int root , int L, int R, int x){    if (tree[root].lc == L && tree[root].rc == R){        tree[root].sum += x*(R-L+1);        tree[root].add += x;        return;    }    pushdown(root,tree[root].rc-tree[root].lc+1);    int mid = (tree[root].lc+tree[root].rc)>>1;    if (R<=mid) update(root<<1,L,R,x);    else if (L>mid) update(root<<1|1,L,R,x);    else {        update(root<<1,L,mid,x);        update(root<<1|1,mid+1,R,x);    }}void query(int root, int L, int R){     if (L==tree[root].lc && R==tree[root].rc) {         ans += tree[root].sum;         return;     }     pushdown(root,tree[root].rc-tree[root].lc+1);     int mid = (tree[root].lc+tree[root].rc)>>1;     if (R<=mid) query(root<<1,L,R);     else if (L>mid) query(root<<1|1,L,R);     else {        query(root<<1,L,mid);        query(root<<1|1,mid+1,R);     }}void init(){   for (int i=1; i<=n; i++) scanf("%d",&h[i]);   sort(h+1,h+n+1);   build(1,1,n);}int kase = 0;int main(){    int s1,s2;    while (scanf("%d %d %d",&n,&m,&k)!=EOF){        init();        int high = 1;        while (m--){            scanf("%d %d",&a,&b);            s1 = lower_bound(h+1,h+n+1,high)-h;            s2 = lower_bound(h+1,h+n+1,a)-h;            if (s2>n) s2 = n;            while (h[s1]<=high) s1++;            while (a<h[s2]) s2--;            if (s1<=s2) update(1,s1,s2,1);            high = b;        }        int total = 0;        for (int i=1; i<=n; i++) {            ans = 0;            query(1,i,i);            if (ans>=k) total++;        }        printf("Case %d: %d\n",++kase,total);    }    return 0;}



原创粉丝点击