思路讲解
如何使用树状数组代替平衡树
其实我主要不会的是怎么查前驱后继
想复杂了,这个其实是用二分做的。
那check函数怎么写呢?
不难发现一个性质,就是如果我要组成k个对
那么一定可以由k个最大的数作底座(当然你想反过来也可以)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| inline bool check(ll k){ int j=N; ll res=0; for(int i=N-k;i>=1 && j>N-k;--i){ if(A[j]>=A[i]*2){ ++res; j-=1; } } if(res>=k){ return true; }else{ return false; } }
|
其实我之前的做法的问题就是“内讧”,自己抢自己的。
AC代码
https://atcoder.jp/contests/abc388/submissions/61633977
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| #include <iostream> #include <cstring> #include <algorithm> #include <deque> #include <queue> #include <vector> #include <set> #include <map> #include <unordered_map> #include <cmath> #include <bitset> #include <iterator> #include <random> #include <iomanip> #include <cctype> #include <array>
typedef long long ll; typedef std::pair<ll,ll> pll; typedef std::array<ll,3> arr; const ll MAXN=static_cast<ll>(5e5)+117;
ll N,T,A[MAXN];
inline bool check(ll k){ int j=N; ll res=0; for(int i=N-k;i>=1 && j>N-k;--i){ if(A[j]>=A[i]*2){ ++res; j-=1; } } if(res>=k){ return true; }else{ return false; } }
int main() { std::ios::sync_with_stdio(false); std::cin.tie(0);std::cout.tie(0); std::cin>>N; for(int i=1;i<=N;++i){ std::cin>>A[i]; } ll l=0,r=N/2; while (l<r) { ll mid=l+r+1>>1; if(check(mid)){ l=mid; }else{ r=mid-1; } } std::cout<<l<<"\n"; return 0; }
|
心路历程(WA,TLE,MLE……)
用这个multiset可以实现查前继后驱
但事实证明贪心的选择A以及A*2的后驱还是有问题
WA https://atcoder.jp/contests/abc388/submissions/61623225
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| #include <iostream> #include <cstring> #include <algorithm> #include <deque> #include <queue> #include <vector> #include <set> #include <map> #include <unordered_map> #include <cmath> #include <bitset> #include <iterator> #include <random> #include <iomanip> #include <cctype> #include <array>
typedef long long ll; typedef std::pair<ll,ll> pll; typedef std::array<ll,3> arr; const ll MAXN=static_cast<ll>(5e5)+117; std::multiset<ll> tr;
ll N,T,A[MAXN];
int main() { std::ios::sync_with_stdio(false); std::cin.tie(0);std::cout.tie(0); std::cin>>N; for(int i=1;i<=N;++i){ std::cin>>A[i]; tr.insert(A[i]); } ll ans=0; for(int i=1;i<=N;++i){ std::multiset<ll>::iterator its=tr.find(A[i]); if(its==tr.end()) continue; tr.insert(A[i]*2); std::multiset<ll>::iterator it=tr.find(A[i]*2); std::multiset<ll>::iterator trEnd=std::prev(tr.end()); if(it==trEnd){ tr.erase(it); continue; } std::multiset<ll>::iterator nextIt = std::next(it); tr.erase(its); tr.erase(it); tr.erase(nextIt); ++ans; } std::cout<<ans<<"\n"; return 0; }
|