Submission #1331586

#TimeUsernameProblemLanguageResultExecution timeMemory
1331586phamducluongTricks of the Trade (CEOI23_trade)C++17
10 / 100
12 ms13236 KiB
#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>

//using namespace __gnu_pbds;
using namespace std;
using ll=long long;
//typedef tree<int,null_type,less_equal<int>,rb_tree_tag, tree_order_statistics_node_update> ordered_set;
#define mem(a,x)       memset(a,x,sizeof(a))
#define int            long long
#define fast(s)        s.reserve(2000); s.max_load_factor(0.5);
#define F              first
#define S              second
#define pii            pair<int,int>
#define iii            tuple<int,int,int>
#define all(p)         p.begin(), p.end()
template<typename T> bool maximum(T &A, const T &B) {return A<B? A=B, true: false;}
template<typename T> bool minimum(T &A, const T &B) {return A>B? A=B, true: false;}
template<typename T> T gcd(T t) {return t;}
template<typename T, typename... Args> T gcd(T t, Args... args) {return __gcd(t,args...);};
void print(bool condition=1) {cout<<(condition? "YES\n": "NO\n");}
const int mod=1e9+19972207;
const int base=256;
const int INF=1e18;
const int N=2e5+5, M=5e6;
int n, k, c[N], s[N], f[N], opt[N], best[N], res=-INF, len;
vector<int> num, cand, add[N], del[N];
multiset<int> ms;
void file()
{
    #define task "codeforces"
    if(fopen(task".inp","r"))
    {
        freopen(task".inp","r",stdin);
        freopen(task".out","w",stdout);
    }
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}
struct Persistent
{
    int sum[M], cnt[M], L[M], R[M];
    int idx=0, ver[N];
    int new_node()
    {
        ++idx;
        sum[idx]=cnt[idx]=0;
        L[idx]=R[idx]=0;
        return idx;
    }
    int Build(int l, int r)
    {
        int p=new_node();
        if(l==r) return p;
        int mid=(l+r)>>1;
        L[p]=Build(l,mid);
        R[p]=Build(mid+1,r);
        return p;
    }
    int update(int id, int l, int r, int i)
    {
        int p=new_node();
        if(l==r)
        {
            sum[p]=sum[id]+num[i-1];
            cnt[p]=cnt[id]+1;
            return p;
        }
        int mid=(l+r)>>1;
        if(i<=mid)
        {
            L[p]=update(L[id],l,mid,i);
            R[p]=R[id];
        }
        else
        {
            L[p]=L[id];
            R[p]=update(R[id],mid+1,r,i);
        }
        sum[p]=sum[L[p]]+sum[R[p]];
        cnt[p]=cnt[L[p]]+cnt[R[p]];
        return p;
    }
    int find_kth(int ptl, int ptr, int l, int r, int k)
    {
        if(l==r) return num[l-1];
        int mid=(l+r)>>1;
        int _count=cnt[R[ptr]]-cnt[R[ptl]];
        if(_count>=k) return find_kth(R[ptl],R[ptr],mid+1,r,k);
        return find_kth(L[ptl],L[ptr],l,mid,k-_count);
    }
    int get(int ptl, int ptr, int l, int r, int k)
    {
        if(l==r) return k*num[l-1];
        int mid=(l+r)>>1;
        int _count=cnt[R[ptr]]-cnt[R[ptl]];
        if(_count>=k) return get(R[ptl],R[ptr],mid+1,r,k);
        return get(L[ptl],L[ptr],l,mid,k-_count)+sum[R[ptr]]-sum[R[ptl]];
    }
} pst;
int cost(int l, int r)
{
    if(r-l+1<k) return -INF;
    return pst.get(pst.ver[l-1],pst.ver[r],1,len,k)-(f[r]-f[l-1]);
}
void dnc(int l, int r, int optl, int optr)
{
    if(l>r) return;
    int mid=(l+r)>>1;
    for(int i=optl; i<=optr; ++i)
        if(maximum(best[mid],cost(mid,i)))
            opt[mid]=i;
    dnc(l,mid-1,optl,opt[mid]);
    dnc(mid+1,r,opt[mid],optr);
}
void Solve()
{
    cin>>n>>k;
    for(int i=1; i<=n; ++i) cin>>c[i];
    for(int i=1; i<=n; ++i) cin>>s[i];
    for(int i=1; i<=n; ++i) f[i]=f[i-1]+c[i];
    for(int i=1; i<=n; ++i) num.push_back(s[i]);
    sort(all(num));
    num.erase(unique(all(num)),num.end());
    len=(int)num.size();
    pst.ver[0]=pst.Build(1,len);
    for(int i=1; i<=n; ++i)
    {
        int p=upper_bound(all(num),s[i])-num.begin();
        pst.ver[i]=pst.update(pst.ver[i-1],1,len,p);
    }
    for(int i=1; i<=n; ++i)
    {
        opt[i]=-1;
        best[i]=-INF;
    }
    dnc(1,n-k+1,1,n);
    for(int i=1; i<=n; ++i)
        maximum(res,best[i]);
    for(int i=1; i<=n; ++i)
        if(best[i]==res) cand.push_back(i);
    for(int i=0; i<(int)cand.size(); ++i)
    {
        int l=cand[i];
        int x=opt[l], y=(i+1==(int)cand.size()? n: opt[cand[i+1]]);
        for(int z=x; z<=y; ++z)
        {
            if(cost(l,z)==res)
            {
                int limit=pst.find_kth(pst.ver[l-1],pst.ver[z],1,len,k);
                add[l].push_back(limit);
                del[z+1].push_back(limit);
            }
        }
    }
    cout<<res<<"\n";
}
signed main()
{
    file();
    Solve();
    return 0;
}

Compilation message (stderr)

trade.cpp: In function 'void file()':
trade.cpp:33:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   33 |         freopen(task".inp","r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
trade.cpp:34:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   34 |         freopen(task".out","w",stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...