CF 609F,线段树上二分 + set维护
(。・∀・)ノ゙嗨大家好,sb我又回来切题了(因为不切大概就要弱死了)
题目大意:在数轴上给定n只青蛙,每只青蛙有一个舌头长度,每只青蛙能吃落在他右边不超过舌头长的蚊子,吃了蚊子蛇头能长长,多只青蛙能吃到则取最左边的一只。
解:原来我的想法是线段树维护区间最小值然后set维护一下看舌头伸长后能吃哪些蚊子。但是由于距离需要离散化,所以导致这个做法细节会非常爆炸。看了一下题解,非常巧妙,维护区间青蛙长度伸到的最右的位置,然后直接在线段树上二分,因为如果左右一块可以覆盖到当前蚊子,肯定是走左边,不然查询右边。
有个trick(其实是我自己傻逼了),如果set里面放的是二元组,但是小于重载只判了一个,那么第二个元不一样的东西也会看作一样,不开multiset就会因为重复插不进去,另外这里记载一个上次周赛的sb错误,就是multiset如果erase(构造函数)的话,不是删除第一个该结构,而是相同的全部删掉,因此如果想删掉第一个的话,用返回迭代器的lower_bound或者find才行。
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <utility> 5 #include <map> 6 #include <string> 7 #include <cmath> 8 #include <vector> 9 #include <cstring> 10 #include <stack> 11 #include <set> 12 #include <queue> 13 14 using namespace std; 15 16 #define SQR(x) ((x)*(x)) 17 #define LL long long 18 #define LOWBIT(x) ((x)&(-(x))) 19 #define PB push_back 20 #define MP make_pair 21 #define SQR(x) ((x)*(x)) 22 #define LSON(x) ((x)<<1) 23 #define RSON(x) (((x)<<1)+1) 24 25 26 #define MAXN 211111 27 28 const double EPS = 1e-6; 29 30 struct data{ 31 int p, sz; 32 data(int a = 0, int b = 0): p(a), sz(b) {} 33 bool operator < (const data &rhs) const { 34 return p > rhs.p; 35 } 36 }; 37 38 vector <pair<int, pair<int, int > > > a; 39 multiset <data > s; 40 int cnt[MAXN], stp[MAXN]; 41 int n, m; 42 LL ans[MAXN], ans2[MAXN]; 43 44 LL len[MAXN]; 45 46 struct SegTree{ 47 LL maxx[MAXN*4]; 48 int l[MAXN*4], r[MAXN*4], m[MAXN*4]; 49 int gx, gy; 50 LL gz; 51 inline void setting(int aa = 0, int bb = 0, LL cc = 0) { 52 gx = aa; gy = bb; gz = cc; 53 } 54 void updata(const int &kok) { 55 if (l[kok] == r[kok]) ; 56 else { 57 maxx[kok] = max(maxx[kok], maxx[LSON(kok)]); 58 maxx[kok] = max(maxx[kok], maxx[RSON(kok)]); 59 } 60 } 61 void build(int kok, int ll, int rr) { 62 l[kok] = ll; r[kok] = rr; 63 if (ll == rr) { 64 maxx[kok] = len[ll]; 65 return ; 66 } 67 m[kok] = (ll + rr) >> 1; 68 build(LSON(kok), ll, m[kok]); 69 build(RSON(kok), m[kok] + 1, rr); 70 updata(kok); 71 } 72 void insert(int kok = 1) { 73 if (l[kok] == r[kok]) { 74 maxx[kok] = gz; 75 return ; 76 } 77 if (gx <= m[kok]) insert(LSON(kok)); 78 else insert(RSON(kok)); 79 updata(kok); 80 } 81 int query(int kok = 1) { 82 if (maxx[kok] < gz) return -1; 83 if (stp[l[kok]] > gz) return -1; 84 if (l[kok] == r[kok]) { 85 return l[kok]; 86 } 87 if (maxx[LSON(kok)] >= gz) return query(LSON(kok)); 88 return query(RSON(kok)); 89 } 90 } ST; 91 92 void init() { 93 cin >> n >> m; 94 int x, y; 95 a.PB(MP(-1, MP(-1, -1))); 96 for (int i = 1; i <= n; ++i) { 97 cin >> x >> y; 98 a.PB(MP(x, MP(y, i))); 99 } 100 sort(a.begin() + 1, a.end()); 101 memset(cnt, 0, sizeof(cnt[0])*(n+10)); 102 for (int i = 1; i <= n; ++i) { 103 stp[i] = a[i].first; 104 len[i] = a[i].first + a[i].second.first; 105 } 106 ST.build(1, 1, n); 107 } 108 109 void solve() { 110 s.clear(); 111 set <data >::iterator it; 112 int p, sz; 113 int t; 114 while (m -- ){ 115 cin >> p >> sz; 116 ST.setting(0, 0, p); 117 t = ST.query(); 118 119 // cout << p <<' ' << sz <<' '<< t << endl; 120 if (t == -1) s.insert(data(p, sz)); 121 else { 122 // cout << len[t] << endl; 123 // if (t == 5) cout << p <<' '<< sz <<endl; 124 len[t] += sz; 125 ++cnt[t]; 126 // cout << len[t] << endl; 127 while (s.size()) { 128 it = s.lower_bound(len[t]); 129 if (it == s.end()) break; 130 // cout << "==============" << endl; 131 // cout << t << ' '<< (*it).p << ' '<< stp[t] << endl; 132 if ((*it).p < stp[t]) break; 133 while (it != s.end()) { 134 if ((*it).p >= stp[t]) { 135 if (t == 5) { 136 // cout << (*it).p << ' '<< (*it).sz << endl; 137 } 138 len[t] += (*it).sz; 139 ++cnt[t]; 140 } 141 else break; 142 s.erase(it++); 143 } 144 } 145 ST.setting(t, 0, len[t]); 146 ST.insert(); 147 // cout << len[t] << endl; 148 } 149 150 } 151 } 152 153 void print() { 154 for (int i = 1; i <= n; ++i) { 155 ans[a[i].second.second] = len[i] - stp[i]; 156 ans2[a[i].second.second] = cnt[i]; 157 } 158 for (int i = 1; i <= n; ++i) { 159 cout << ans2[i] << ' '<< ans[i] << endl; 160 } 161 } 162 163 int main() { 164 // freopen("test.txt", "r", stdin); 165 // freopen("my.txt", "w", stdout ); 166 ios::sync_with_stdio(false); 167 init(); 168 solve(); 169 print(); 170 return 0; 171 }