【线段树】codeforces R159E. Greedy Elevator

http://codeforces.com/contest/257/problem/E

      闲来无事切一下div2的比赛,增强一下自信心,弱暴了=。=,最近卡题卡得要靠div2来涨信心了。

      E题题面很长,但是实际很好读,读完题发现就是一个纯粹的模拟题,不过规模比较大需要用数据结构来维护,一开始觉得平衡树挺方面的,后来发现楼层之后10^5离散化都不用就写成线段树了。

      由于电梯运行时间可能很大,所以不能以秒为单位模拟,但是显然可以以请求电梯以及下电梯的事件来模拟,用线段树判断当前向下的请求以及向上请求总数,判断电梯运行方向,同时顺便求出以该方向运行多久可以满足第一个请求,再于新增加请求时间比较看看哪个事件先发生。。最多2*n个事件,同时每次判断时间复杂度O(logn)

View Code
  1 //By Lin
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<map>
  6 #include<vector>
  7 #define maxn 100010
  8 #define foreach(a,b) for(__typeof(b.begin()) a = b.begin(); a!=b.end(); a++ )
  9 #define Rep(i,n) for(int i = 0; i<n; i++)
 10 using namespace std;
 11 typedef long long LL;
 12 
 13 struct    Segtree{
 14     int left[maxn*4],right[maxn*4];
 15     int    L[maxn*4],R[maxn*4];
 16     int    sum[maxn*4];
 17     void    build(int l,int r,int step){
 18         left[step] = l , right[step] = r;
 19         sum[step] = 0;
 20         L[step] = R[step] = -1;
 21         if ( l == r ) return;
 22         int mid = (l+r)/2;
 23         build( l , mid , step*2 );
 24         build(mid+1, r , step*2+1 );
 25     }
 26     void      updata(int w,int num,int step){
 27         if ( left[step] == right[step] ){
 28             sum[step] += num;
 29             L[step] = R[step] = sum[step]?w:-1;
 30             return;
 31         }
 32         int mid = ( left[step]+right[step])/2;
 33         updata( w , num , w<=mid?(step*2):(step*2+1) );
 34         sum[step] = sum[step*2] + sum[step*2+1];
 35         L[step] = L[step*2+(L[step*2]==-1?1:0)];
 36         R[step] = R[step*2+(R[step*2+1]==-1?0:1)];
 37     }
 38     int        ask(int l,int r,int &g ,int &h,int step){
 39         if ( left[step] == l && right[step] == r ){
 40             g = L[step] , h = R[step];
 41             return sum[step];
 42         }
 43         int mid = ( left[step]+right[step])/2;
 44         if ( r<=mid ) return ask(l,r,g,h,step*2);
 45         else if ( l > mid ) return ask(l,r,g,h,step*2+1);
 46         else{
 47             int g1,g2,h1,h2;
 48             int ret = ask(l,mid,g1,h1,step*2)+ask(mid+1,r,g2,h2,step*2+1);
 49             g = g1!=-1?g1:g2;
 50             h = h2!=-1?h2:h1;
 51             return ret;
 52         }
 53     }
 54 }tree;
 55 
 56 int        n,m;
 57 struct    People{
 58     int t,s,f,id;
 59     void init(int _id){
 60         id = _id;
 61         scanf("%d%d%d", &t, &s, &f );
 62     }
 63     bool friend operator<( const People &a, const People &b){
 64         return a.t<b.t;
 65     }
 66 }data[maxn];
 67 
 68 map<int,vector<int> >    mm;
 69 LL        ans[maxn],now;
 70 
 71 void    updata(int cur){
 72 //    printf("updata %d\n", cur );
 73     foreach( iter , mm[cur] ){
 74 //        printf("iter %d\n" , *iter );
 75         int k = *iter;
 76         if ( k >= 0 ) {
 77             mm[data[k].f].push_back( -data[k].id );
 78             tree.updata( data[k].f, 1, 1);
 79         }
 80         else
 81             ans[-k] = now;
 82     }
 83 //    printf("%d %d\n" , cur , -((int)mm[cur].size()) );
 84     tree.updata( cur , -((int)mm[cur].size()), 1 );
 85     mm[cur].clear();
 86 }
 87 int        main(){
 88     scanf("%d%d", &n, &m );
 89     tree.build(1,m,1);
 90     Rep(i,n) data[i].init(i+1);
 91     sort( data , data+n );
 92 //    printf("ok\n");
 93     int cur = 1, i = 0,g1,h1,g2,h2;
 94     while ( true ){
 95         int num1 = tree.ask(1,cur,g1,h1,1),
 96             num2 = tree.ask(cur,m,g2,h2,1);
 97 //        printf("%d %lld (%d %d %d) (%d %d %d)\n" , cur , now ,num1,g1,h1,num2,g2,h2 );
 98         if ( num1 > num2 ){ 
 99             if ( i<n && data[i].t<=now+cur-h1 ){
100                 cur = cur-(data[i].t-now);
101                 now = data[i].t;
102                 mm[data[i].s].push_back(i);
103                 tree.updata( data[i].s , 1 , 1 );
104                 i++;
105                 continue;
106             }
107             now += cur-h1;
108             cur = h1;
109             updata(cur);
110         }
111         else if ( num1 <= num2 && num2 ){
112             if ( i<n && data[i].t<=now+g2-cur ){
113                 cur = cur+(data[i].t-now);
114                 now = data[i].t;
115                 mm[data[i].s].push_back(i);
116                 tree.updata( data[i].s , 1 , 1 );
117                 i++;
118                 continue;
119             }
120             now += g2-cur;
121             cur = g2;
122             updata(cur);
123         }
124         else{
125             if ( i == n ) break;
126             now = data[i].t;
127             mm[data[i].s].push_back(i);
128             tree.updata( data[i].s , 1 , 1 );
129             i++;
130         }
131     }
132     Rep(i,n) printf("%I64d\n", ans[i+1] );
133     return 0;
134 }

 

posted @ 2013-01-09 02:01  lzqxh  阅读(283)  评论(0编辑  收藏  举报