답안 #538429

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
538429 2022-03-16T20:13:29 Z perchuts Growing Trees (BOI11_grow) C++17
100 / 100
120 ms 2876 KB
#include <bits/stdc++.h>
#define maxn (int)(1e5+51)
#define all(x) x.begin(), x.end()
#define sz(x) (int) x.size()
#define endl '\n'
#define ll long long
#define pb push_back
#define ull unsigned long long
#define ii pair<int,int>
#define iii tuple<int,int,int>
#define inf 2000000001
#define mod 1000000007 //998244353
#define _ ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);

using namespace std;

template<typename X, typename Y> bool ckmin(X& x, const Y& y) { return (y < x) ? (x=y,1):0; }
template<typename X, typename Y> bool ckmax(X& x, const Y& y) { return (x < y) ? (x=y,1):0; }

int n,m,bit[maxn];

void insert(int x,int d){
    while(x<=n)bit[x]+=d,x+=x&(-x);
}

void add(int l,int r,int d){
    insert(l,d);
    insert(r+1,-d);
}

int query(int x){
    int ans = 0;
    while(x){
        ans += bit[x];
        x -= x&(-x);
    }
    return ans;
}

int main(){_
    cin>>n>>m;
    vector<int>v(n);
    for(auto& x:v)cin>>x;
    sort(all(v));
    for(int i=0;i<n;++i)add(i+1,i+1,v[i]);
    // for(int i=1;i<=n;++i)cerr<<query(i)<<" \n"[i==n];
    while(m--){
        char op;cin>>op;
        if(op=='F'){
            int c,h;cin>>c>>h;
            // cerr<<"adding to "<<c<<" smallest elements starting from "<<h<<endl;
            int l = 1, r = n, ans = inf;
            while(l<=r) {
                int md = l + (r-l+1)/2;
                if(query(md)>=h)ans = md, r = md-1;
                else l = md + 1;
            }
            if(ans==inf)continue;
            int lo = ans, hi = min(n,ans + c - 1);//minelement >= h 
            int biggest = query(hi);//maxheight of added element
            // cerr<<"found "<<lo<<" as min index >=h"<<endl;
            // cerr<<"biggest height to be added is "<<biggest<<endl;
            if(biggest!=query(lo)){
                l = 1, r = n, ans = inf;
                while(l<=r){
                    int md = l + (r-l+1)/2;
                    if(query(md)<biggest)ans = md, l = md + 1;
                    else r = md - 1;
                }//ans = largest idx whose height is < biggest
                // cerr<<"added from "<<lo<<" to "<<ans<<endl;
                add(lo,ans,1);//added everyone in interval [query(lo),biggest-1]
                // cerr<<"max index < biggest is"<<ans<<endl;
            }else ans = lo-1;
            //now add to rightmost biggest
            int left = c - (ans - lo + 1), fi = ans + 1;
            l = 1, r = n, ans = inf;
            while(l<=r){
                int md = l + (r-l+1)/2;
                if(query(md)<=biggest)ans = md, l = md + 1;
                else r = md - 1;
            }
            // cerr<<"now, adding from "<<max(ans-left+1,fi)<<" to "<<ans<<endl;
            add(max(ans-left+1,fi),ans,1);
        }else{
            int le,ri;cin>>le>>ri;
            int l = 1, r = n, ans = inf;
            while(l<=r){
                int md = l + (r-l+1)/2;
                if(query(md)>=le)ans = md, r = md - 1;
                else l = md + 1;
            }
            //se lo == infinito, todos os elementos sao menores que le, portanto estou fora do intervalo
            //se hi == infinito, todos os elementos sao maiores que ri, portanto estou fora do intervalo
            int lo = ans;
            l = 1, r = n, ans = inf;
            while(l<=r){
                int md = l + (r-l+1)/2;
                if(query(md)<=ri)ans = md, l = md + 1;
                else r = md - 1;
            }
            int hi = ans;
            if(max(lo,hi)==inf)cout<<0<<endl;
            else cout<<hi-lo+1<<endl;
        }
        // for(int i=1;i<=n;++i)cerr<<query(i)<<" \n"[i==n];
    }
}
# 결과 실행 시간 메모리 Grader output
1 Correct 63 ms 1228 KB Output is correct
2 Correct 109 ms 2688 KB Output is correct
3 Correct 55 ms 2616 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 2 ms 340 KB Output is correct
3 Correct 2 ms 340 KB Output is correct
4 Correct 2 ms 340 KB Output is correct
5 Correct 53 ms 1400 KB Output is correct
6 Correct 67 ms 1612 KB Output is correct
7 Correct 4 ms 340 KB Output is correct
8 Correct 27 ms 1128 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 50 ms 744 KB Output is correct
2 Correct 60 ms 1756 KB Output is correct
3 Correct 2 ms 340 KB Output is correct
4 Correct 42 ms 1236 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 46 ms 804 KB Output is correct
2 Correct 60 ms 1620 KB Output is correct
3 Correct 6 ms 468 KB Output is correct
4 Correct 72 ms 1684 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 66 ms 1064 KB Output is correct
2 Correct 86 ms 2300 KB Output is correct
3 Correct 17 ms 820 KB Output is correct
4 Correct 47 ms 2284 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 85 ms 996 KB Output is correct
2 Correct 100 ms 2292 KB Output is correct
3 Correct 62 ms 2516 KB Output is correct
4 Correct 16 ms 828 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 64 ms 1176 KB Output is correct
2 Correct 81 ms 2376 KB Output is correct
3 Correct 71 ms 2600 KB Output is correct
4 Correct 20 ms 852 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 105 ms 1148 KB Output is correct
2 Correct 103 ms 2216 KB Output is correct
3 Correct 28 ms 1736 KB Output is correct
4 Correct 54 ms 2236 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 78 ms 1228 KB Output is correct
2 Correct 102 ms 2680 KB Output is correct
3 Correct 120 ms 2876 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 101 ms 1644 KB Output is correct