#include <iostream> #include <set> #include <cstdio> //#define DEBUG using namespace std; struct Fish { long long mass; int deadIter; bool operator<(const Fish& other) const { return this->mass < other.mass; } }; struct FishCmp { bool operator()(const Fish* lhs, const Fish* rhs) const { return *rhs < *lhs; } }; istream& operator>>(istream& is, Fish& fish) { fish.deadIter = -1; return is>>fish.mass; } const int MAX_FISH = 400001; Fish tab[MAX_FISH]; //std::multiset<Fish> fishes; std::multiset<Fish*, FishCmp> fishes; typedef multiset<Fish*, FishCmp>::iterator FishIter; int n,q,x; Fish s,k,w; int simulate(int i, FishIter& nextPos) { #if defined(HOME) && defined(DEBUG) printf("simulate %d; %lld->%lld\n", i, s.mass, k.mass); #endif nextPos = fishes.upper_bound(&s); FishIter currentPos = nextPos; bool hasNext=(currentPos!=fishes.begin()); if(hasNext) --nextPos; int cnt=0; while(s<k) { if(hasNext && (**nextPos) < s && (*nextPos)->deadIter != i) { #if defined(HOME) && defined(DEBUG) printf("recursion -> %lld can eat now %lld instead of current %lld\n", s.mass, (*nextPos)->mass, (currentPos==fishes.end()?-1LL:(*currentPos)->mass)); #endif cnt += simulate(i, nextPos); } else if(currentPos == fishes.end()) { break; } else if((*currentPos)->deadIter == i) { return cnt; } else { (*currentPos)->deadIter = i; s.mass += (*currentPos)->mass; ++cnt; #if defined(HOME) && defined(DEBUG) printf("eating fish %lld; now mass is %lld/%lld\n", (*currentPos)->mass, s.mass, k.mass); #endif currentPos++; } } return s<k ? -1 : cnt; } int simulate(int i) { #if defined(HOME) && defined(DEBUG) puts("Available fishes are:"); for(Fish* fish : fishes) printf("%lld\n", fish->mass); #endif FishIter iter; return simulate(i, iter); } int main() { #if !defined(HOME) || !defined(DEBUG) ios_base::sync_with_stdio(0); #endif cin>>n; for(int i=0;i<n;++i) { cin>>tab[i]; fishes.insert(&tab[i]); } #if defined(HOME) && defined(DEBUG) puts("Loaded fishes are:"); for(Fish* fish : fishes) printf("%lld\n", fish->mass); #endif cin>>q; for(int i=0;i<q;++i) { cin>>x; if(x==1) { cin>>s>>k; cout<<simulate(i)<<endl; } else if(x==2) { cin>>tab[n++]; fishes.insert(&tab[n-1]); } else { // x==3 cin>>w; fishes.erase(fishes.lower_bound(&w)); } } return 0; }
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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | #include <iostream> #include <set> #include <cstdio> //#define DEBUG using namespace std; struct Fish { long long mass; int deadIter; bool operator<(const Fish& other) const { return this->mass < other.mass; } }; struct FishCmp { bool operator()(const Fish* lhs, const Fish* rhs) const { return *rhs < *lhs; } }; istream& operator>>(istream& is, Fish& fish) { fish.deadIter = -1; return is>>fish.mass; } const int MAX_FISH = 400001; Fish tab[MAX_FISH]; //std::multiset<Fish> fishes; std::multiset<Fish*, FishCmp> fishes; typedef multiset<Fish*, FishCmp>::iterator FishIter; int n,q,x; Fish s,k,w; int simulate(int i, FishIter& nextPos) { #if defined(HOME) && defined(DEBUG) printf("simulate %d; %lld->%lld\n", i, s.mass, k.mass); #endif nextPos = fishes.upper_bound(&s); FishIter currentPos = nextPos; bool hasNext=(currentPos!=fishes.begin()); if(hasNext) --nextPos; int cnt=0; while(s<k) { if(hasNext && (**nextPos) < s && (*nextPos)->deadIter != i) { #if defined(HOME) && defined(DEBUG) printf("recursion -> %lld can eat now %lld instead of current %lld\n", s.mass, (*nextPos)->mass, (currentPos==fishes.end()?-1LL:(*currentPos)->mass)); #endif cnt += simulate(i, nextPos); } else if(currentPos == fishes.end()) { break; } else if((*currentPos)->deadIter == i) { return cnt; } else { (*currentPos)->deadIter = i; s.mass += (*currentPos)->mass; ++cnt; #if defined(HOME) && defined(DEBUG) printf("eating fish %lld; now mass is %lld/%lld\n", (*currentPos)->mass, s.mass, k.mass); #endif currentPos++; } } return s<k ? -1 : cnt; } int simulate(int i) { #if defined(HOME) && defined(DEBUG) puts("Available fishes are:"); for(Fish* fish : fishes) printf("%lld\n", fish->mass); #endif FishIter iter; return simulate(i, iter); } int main() { #if !defined(HOME) || !defined(DEBUG) ios_base::sync_with_stdio(0); #endif cin>>n; for(int i=0;i<n;++i) { cin>>tab[i]; fishes.insert(&tab[i]); } #if defined(HOME) && defined(DEBUG) puts("Loaded fishes are:"); for(Fish* fish : fishes) printf("%lld\n", fish->mass); #endif cin>>q; for(int i=0;i<q;++i) { cin>>x; if(x==1) { cin>>s>>k; cout<<simulate(i)<<endl; } else if(x==2) { cin>>tab[n++]; fishes.insert(&tab[n-1]); } else { // x==3 cin>>w; fishes.erase(fishes.lower_bound(&w)); } } return 0; } |