【datastruct】codeforces 173E. Camping Groups

http://codeforces.com/problemset/problem/173/E

        好久没写题解了,在家木有咖啡木有战斗力啊,写什么卡什么=。=,还好最拿手的数据结构顺利一点。。

        题意是这样的有n个人,每个人有两个属性年龄a和支持率b,有个闲得蛋疼的人要在其中选若干人组成一个小组,必须满足以下两个条件,A.必须有一个leader,且leader必须是其中支持率最搞的一个人;B.小组中每个人与leader的年龄差距不得超过K。。。之后有若干个询问,问每次询问如果将i,j两个人弄到一个小组里,那这个小组最多能包含多少个人?

       赤裸裸的数据结构,首先预处理每个人当leader的时候,小组人数上限,显然离散化年龄之后,按b排序操作,用数状数组就可以简单搞定这个问题。之后考虑每个询问,可以发现同时包含i,j的小组的leader,其年龄肯定处在某一个区间的,设置为L,R。同时leader的支持率要大于等于max(bi,bj)。。想到这里之后我们就可以很暴力的将询问根据max(bi,bj)排序,然后逐渐剔除支持率不合格的leader,同时用线段树求出区间最值就可以了。。一开始我没怎么想直接线段树每个节点套一个multiset,nlognlogn超时了=。=。。之后稍微想一个发现用单调队列可以优化就套了一个deque,AC...AC完之后发现我太sb了,裸的线段树什么都不用套,在外面发现某个地方最值改变了在去修改线段树不就行了=。=

代码如下(deque版本)

View Code
  1 //By Lin
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<set>
  7 #include<map>
  8 #define maxn 100050
  9 #define Rep(i,n) for(int i = 0; i<n; i++)
 10 #define mp(x,y)  make_pair(x,y)
 11 #define X first
 12 #define Y second
 13 using namespace std;
 14 typedef pair<int,int> pii;
 15 
 16 struct    Node{
 17     int x,y,id,key;
 18 }data[maxn];
 19 bool    cmp1( const Node &a , const Node &b){
 20     return a.y < b.y;
 21 }
 22 bool    cmp2( const Node &a , const Node &b){
 23     return a.id < b.id;
 24 }
 25 int        xcnt,n,xx[maxn],K;
 26 int        num[maxn],m;
 27 map<int,int> mx;
 28 
 29 struct    Ask{
 30     int l,r,id,y;
 31 }asks[maxn];
 32 int        ans[maxn];
 33 bool    cmp3( const Ask &a , const Ask &b){
 34     return a.y < b.y;
 35 }
 36 void    get(int &x,int key,bool flag ){
 37     int g = 0, h = xcnt-1; 
 38     x = -1;
 39     while ( g<=h ) {
 40         int mid = (g+h)/2;
 41         if ( !flag ){
 42             if ( xx[mid] >= key ) x = mid,h = mid-1;
 43             else g = mid+1;
 44         }
 45         else{
 46             if ( xx[mid] <= key ) x = mid,g = mid+1;
 47             else h = mid-1;
 48         }
 49     }
 50 }
 51 
 52 struct    Segtree{
 53     int    left[maxn*4],right[maxn*4];
 54     deque<pii> que[maxn*4];
 55     void build(int l,int r,int step){
 56         left[step] = l , right[step] = r;
 57         while ( !que[step].empty()  ) que[step].pop_front();
 58         if ( l == r ) return;
 59         int mid = (left[step]+right[step])/2;
 60         build( l , mid ,step*2 );
 61         build(mid+1, r ,step*2+1 );
 62     }
 63     void insert(int w,pii tmp,bool flag , int step){
 64         if ( flag ){
 65             while ( !que[step].empty() && que[step].back().Y <= tmp.Y )
 66                 que[step].pop_back();
 67             que[step].push_back( tmp );
 68         }
 69         else
 70             while ( !que[step].empty() && que[step].front().X <= tmp.X )
 71                 que[step].pop_front();
 72         
 73         if ( left[step] == right[step] ) return;
 74         int mid = (left[step]+right[step])/2;
 75         if ( w <= mid ) insert( w , tmp , flag , step*2 );
 76         else insert( w , tmp , flag , step*2+1 );
 77     }
 78     int    ask(int l,int r,int step){
 79         if ( left[step] == l && right[step] == r ) 
 80             return que[step].empty()?-1:(que[step].front().Y);
 81         int mid = (left[step]+right[step])/2;
 82         if ( r <= mid ) return ask(l,r,step*2);
 83         else if ( l > mid ) return ask(l,r,step*2+1);
 84         else
 85             return max( ask(l,mid,step*2), ask(mid+1,r,step*2+1) );
 86     }
 87 }tree;
 88 
 89 int        tol[maxn];
 90 void    insert(int x){
 91     x++;
 92     for (int i = x; i<=xcnt+10; i+=i&(-i) ) tol[i]++;
 93 }
 94 int        ask(int x){
 95     x++;
 96     int ret = 0;
 97     for (int i = x; i>=1; i-=i&(-i) ) ret += tol[i];
 98     return ret;
 99 }
100 int        main(){
101     set<int> gg;
102     gg.insert( 1 );
103     gg.insert( 2 );
104     scanf("%d%d", &n, &K );
105     Rep(i,n) scanf("%d", &data[i].y );
106     Rep(i,n) {
107         scanf("%d", &data[i].x );
108         data[i].id = i;
109         xx[i] = data[i].x;
110     }
111     sort( xx , xx+n );
112     xcnt = unique( xx, xx+n) - xx;
113     Rep(i,xcnt) mx[xx[i]] = i;
114     Rep(i,n) data[i].x = mx[data[i].x];
115     sort( data , data+n, cmp1 );
116     for (int i = 0,j; i<n; i++  ){
117         for ( j = i; j<n && data[j].y == data[i].y; j++)
118             insert(data[j].x);
119         for ( int k = i; k<j; k++ ){
120             int l , r;
121             get( l,xx[data[k].x]-K,0 );
122             get( r,xx[data[k].x]+K,1 );
123             data[k].key = ask(r)-ask(l-1);
124         }
125         i = j-1;
126     }
127     sort( data , data+n, cmp2 );
128     scanf("%d", &m );
129     Rep(i,m) {
130         int l1,l2,r1,r2,l,r,x,y;
131         scanf("%d%d", &x, &y );
132         asks[i].y = max( data[x-1].y , data[y-1].y );
133         x = xx[data[x-1].x], y = xx[data[y-1].x];
134         get(l1,x-K,0);    get(r1,x+K,1);
135         get(l2,y-K,0);    get(r2,y+K,1);
136         l = max(l1,l2);
137         r = min(r1,r2);
138         asks[i].l = l , asks[i].r = r;
139         asks[i].id = i;
140     }
141     sort( data , data+n , cmp1 );
142     tree.build(0,xcnt,1);
143     Rep(i,n) tree.insert( data[i].x , mp(data[i].y,data[i].key) , 1 , 1 );
144     sort( asks , asks+m , cmp3 );
145     for (int i = 0 , j = 0; i<m; i++){
146         while ( j<n && data[j].y < asks[i].y ) {
147             tree.insert( data[j].x,mp(data[j].y,data[j].key),0,1 );
148             j++;
149         }
150         if ( asks[i].l > asks[i].r ) ans[asks[i].id]  = -1;
151         else ans[asks[i].id] = tree.ask( asks[i].l, asks[i].r, 1 );
152     }
153     for (int i = 0; i<m; i++) printf("%d\n" , ans[i] );
154     return 0;
155 }

 

posted @ 2013-01-05 22:23  lzqxh  阅读(297)  评论(0编辑  收藏  举报