HDU 3577 Fast Arrangement (线段树区间更新)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3577

题意不好理解,给你数字k表示这里车最多同时坐k个人,然后有q个询问,每个询问是每个人的上车和下车时间,每个人按次序上车,问哪些人能上车输出他们的序号。

这题用线段树的成段更新,把每个人的上下车时间看做一个线段,每次上车就把这个区间都加1,但是上车的前提是这个区间上的最大值不超过k。有个坑点就是一个人上下车的时间是左闭右开区间,可以想到要是一个人下车,另一个人上车,这个情况下这个点的大小还是不变的。还有注意格式...

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 using namespace std;
  5 const int MAXN = 1e6 + 5;
  6 struct segtree {
  7     int l , r , sum , add;
  8 }T[MAXN << 2];
  9 int x[MAXN / 10] , y[MAXN / 10] , ans[MAXN / 10];
 10 
 11 void init(int p , int l , int r) {
 12     int mid = (l + r) >> 1;
 13     T[p].l = l , T[p].r = r , T[p].add = 0;
 14     if(l == r) {
 15         T[p].sum = 0;
 16         return ;
 17     }
 18     init(p << 1 , l , mid);
 19     init((p << 1)|1 , mid + 1 , r);
 20     T[p].sum = max(T[p << 1].sum , T[(p << 1)|1].sum);
 21 }
 22 
 23 void updata(int p , int l , int r , int val) {
 24     int mid = (T[p].l + T[p].r) >> 1;
 25     if(l == T[p].l && T[p].r == r) {
 26         T[p].sum += val;
 27         T[p].add += val;
 28         return ;
 29     }
 30     if(T[p].add) {
 31         T[p << 1].sum += T[p].add;
 32         T[p << 1].add += T[p].add;
 33         T[(p << 1)|1].sum += T[p].add;
 34         T[(p << 1)|1].add += T[p].add;
 35         T[p].add = 0;
 36     }
 37     if(r <= mid) {
 38         updata(p << 1 , l , r , val);
 39     }
 40     else if(l > mid) {
 41         updata((p << 1)|1 , l , r , val);
 42     }
 43     else {
 44         updata(p << 1 , l , mid ,val);
 45         updata((p << 1)|1 , mid + 1 , r , val);
 46     }
 47     T[p].sum = max(T[p << 1].sum , max(T[(p << 1)|1].sum , T[p].sum));
 48 }
 49 
 50 int query(int p , int l , int r) {
 51     int mid = (T[p].l + T[p].r) >> 1;
 52     if(l == T[p].l && T[p].r == r) {
 53         return T[p].sum;
 54     }
 55     if(T[p].add) {
 56         T[p << 1].sum += T[p].add;
 57         T[p << 1].add += T[p].add;
 58         T[(p << 1)|1].sum += T[p].add;
 59         T[(p << 1)|1].add += T[p].add;
 60         T[p].add = 0;
 61     }
 62     if(r <= mid) {
 63         return query(p << 1 , l , r);
 64     }
 65     else if(l > mid) {
 66         return query((p << 1)|1 , l , r);
 67     }
 68     else {
 69         return max(query(p << 1 , l , mid) , query((p << 1)|1 , mid + 1 , r));
 70     }
 71 }
 72 
 73 int main() 
 74 {
 75     int t , k , m;
 76     scanf("%d" , &t);
 77     for(int ca = 1 ; ca <= t ; ca++) {
 78         scanf("%d %d" , &k , &m);
 79         int len = -1;
 80         for(int i = 1 ; i <= m ; i++) {
 81             scanf("%d %d" , x + i , y + i);
 82             y[i]--;
 83             len = max(x[i] , len);
 84             len = max(y[i] , len);
 85         }
 86         init(1 , 1 , len);
 87         int cont = 0;
 88         for(int i = 1 ; i <= m ; i++) {
 89             int temp = query(1 , x[i] , y[i]);
 90             if(temp < k) {
 91                 ans[++cont] = i;
 92                 updata(1 , x[i] , y[i] , 1);
 93             }
 94         }
 95         printf("Case %d:\n" , ca);
 96         for(int i = 1 ; i <= cont ; i++) {
 97             printf("%d " , ans[i]);
 98         }
 99         printf("\n\n");
100     }
101 }

 

posted @ 2016-04-05 13:48  Recoder  阅读(495)  评论(1编辑  收藏  举报