【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 }