제출 #1336165

#제출 시각아이디문제언어결과실행 시간메모리
1336165KhoaDuyTricks of the Trade (CEOI23_trade)C++20
컴파일 에러
0 ms0 KiB
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ll long long

const ll limit=-1e18;
struct node{
    int delidx=-1,addidx=-1;
};

ll ans=limit;
set<pair<int,int>> se;
ll curr=0;
const int MAXN=3*1e5;
ll pre[MAXN+1];
int c[MAXN+1],s[MAXN+1];
int k;

// Replaced std::stack with std::vector for faster contiguous memory access.
// Replaced bool with char to avoid vector<bool> bitfield overhead.
vector<node> st;
vector<char> rb; 
int L,R;
node breh;
int opt[MAXN+2];

inline ll calc(){
    return (curr-(pre[R]-pre[L-1]));
}

inline void reset(){
    curr=0;
    st.clear(); // O(N) cleanup, much faster than manually popping
    rb.clear();
    L=0,R=0;
    se.clear(); // Massively faster than erasing element by element
}

inline void add(int idx){
    node nxt;
    curr+=s[idx];
    se.insert({s[idx],idx});
    nxt.addidx=idx;
    if(se.size()>k){
        int idx2=(*se.begin()).second;
        nxt.delidx=idx2;
        se.erase(se.begin());
        curr-=s[idx2];
    }
    st.push_back(nxt);
}

inline void rollback(int cnt){
    for(int bruh=0;bruh<cnt;bruh++){
        node temp=st.back();
        st.pop_back();
        if(!rb.back()){
            L++;
        }
        else{
            R--;
        }
        if(temp.delidx!=-1){
            se.insert({s[temp.delidx],temp.delidx});
            curr+=s[temp.delidx];
        }
        if(temp.addidx!=-1){
            se.erase({s[temp.addidx],temp.addidx});
            curr-=s[temp.addidx];
        }
        rb.pop_back();
    }
}

inline void moveL(int cnt){
    for(int bruh=0;bruh<cnt;bruh++){
        L--;
        if(L<=R){
            add(L);
        }
        else{
            st.push_back(breh);
        }
        rb.push_back(0); // 0 acts as false
    }
}

inline void moveR(int cnt){
    for(int bruh=0;bruh<cnt;bruh++){
        R++;
        if(L<=R){
            add(R);
        }
        else{
            st.push_back(breh);
        }
        rb.push_back(1); // 1 acts as true
    }
}

int e[MAXN+1];
ll bst[MAXN+1];

void dnc(int l,int r,int optl,int optr){
    int mid=((l+r)>>1);
    moveL(r-mid);
    int optm=-1;
    ll val=limit;
    for(int i=optl;i<=optr;i++){
        ll nxt=calc();
        if(i-mid+1>=k&&nxt>val){
            val=nxt;
            optm=i;
        }
        if(i+1<=optr){
            moveR(1);
        }
    }
    bst[mid]=val;
    opt[mid]=optm;
    ans=max(ans,val);
    rollback(optr-optl+r-mid);
    if(l<=mid-1){
        moveL(r-mid+1);
        dnc(l,mid-1,optl,optm);
        rollback(r-mid+1);
    }
    if(mid+1<=r){
        moveR(optm-optl);
        dnc(mid+1,r,optm,optr);
        rollback(optm-optl);
    }
}

bool del[MAXN+1];
pair<int,int> Tid={0,-1};

inline pair<int,int> TT(const pair<int,int> &le, const pair<int,int> &ri){
    return le > ri ? le : ri; // Slightly faster than max() overhead
}

struct segtree{
    vector<pair<int,int>> seg;
    int n,lg;
    inline void refresh(int v){
        seg[v]=TT(seg[v<<1],seg[(v<<1)|1]);
    }
    void build(vector<int> &a){
        n=1;
        while(n<a.size()){
            n<<=1;
        }
        lg=__lg(n);
        seg.assign(n<<1,Tid);
        for(int i=0;i<a.size();i++){
            seg[n+i]={a[i],i};
        }
        for(int i=n-1;i>=1;i--){
            refresh(i);
        }
    }
    inline void update(int l){
        del[l]=true;
        l+=n;
        seg[l]=Tid;
        for(int i=1;i<=lg;i++){
            refresh(l>>i);
        }
    }
    inline pair<int,int> query(int l,int r){
        l+=n,r+=n;
        pair<int,int> curr=Tid;
        for(;l<r;l>>=1,r>>=1){
            if(l&1){
                curr=TT(curr,seg[l]);
                l++;
            }
            if(r&1){
                r--;
                curr=TT(curr,seg[r]);
            }
        }
        return curr;
    }
};

segtree seg;

void dnc_trace(int l,int r,int optl,int optr){
    int mid=((l+r)>>1);
    moveL(r-mid);
    int optm=opt[mid];
    if(bst[mid]==ans){
        moveR(optm-optl);
        for(int i=optm;i<=e[mid];i++){
            if(calc()==ans){
                int idx=seg.query(mid,i+1).second;
                while(idx!=-1&&s[idx]>=(*se.begin()).first){
                    seg.update(idx);
                    idx=seg.query(mid,i+1).second;
                }
            }
            if(i<e[mid]){
                moveR(1);
            }
        }
        rollback(e[mid]-optl);
    }
    rollback(r-mid);
    if(l<=mid-1){
        moveL(r-mid+1);
        dnc_trace(l,mid-1,optl,optm);
        rollback(r-mid+1);
    }
    if(mid+1<=r){
        moveR(optm-optl);
        dnc_trace(mid+1,r,optm,optr);
        rollback(optm-optl);
    }
}

signed main(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    if(fopen("input.txt","r")){
        freopen("input.txt","r",stdin);
    }
    
    // Pre-allocating maximum potential depth bounds to prevent reallocations
    st.reserve(MAXN * 2);
    rb.reserve(MAXN * 2);
    
    int n;
    cin >> n >> k;
    for(int i=1;i<=n;i++){
        cin >> c[i];
        pre[i]=pre[i-1]+c[i];
    }
    s[0]=0;
    for(int i=1;i<=n;i++){
        cin >> s[i];
    }
    L=n-k+1,R=k;
    for(int i=L;i<=R;i++){
        add(i);
    }
    vector<int> a(n+1);
    a[0]=0;
    for(int i=1;i<=n;i++){
        a[i]=s[i];
    }
    seg.build(a);
    dnc(1,n-k+1,k,n);
    opt[n-k+2]=n;
    reset();
    L=n-k+1,R=k;
    for(int i=L;i<=R;i++){
        add(i);
    }
    int last=-1;
    for(int i=n-k+1;i>=1;i--){
        if(bst[i]<ans){
            continue;
        }
        if(last==-1){
            e[i]=n;
        }
        else{
            e[i]=opt[last];
        }
        last=i;
    }
    dnc_trace(1,n-k+1,k,n);
    cout << ans << endl;
    for(int i=1;i<=n;i++){
        cout << (del[i] ? '1' : '0');
    }
    cout << endl;
}

컴파일 시 표준 에러 (stderr) 메시지

trade.cpp: In function 'int main()':
trade.cpp:229:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  229 |         freopen("input.txt","r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/13/string:43,
                 from /usr/include/c++/13/bitset:52,
                 from /usr/include/x86_64-linux-gnu/c++/13/bits/stdc++.h:52,
                 from trade.cpp:4:
/usr/include/c++/13/bits/allocator.h: In destructor 'constexpr std::_Vector_base<char, std::allocator<char> >::_Vector_impl::~_Vector_impl()':
/usr/include/c++/13/bits/allocator.h:184:7: error: inlining failed in call to 'always_inline' 'constexpr std::allocator< <template-parameter-1-1> >::~allocator() noexcept [with _Tp = char]': target specific option mismatch
  184 |       ~allocator() _GLIBCXX_NOTHROW { }
      |       ^
In file included from /usr/include/c++/13/vector:66,
                 from /usr/include/c++/13/functional:64,
                 from /usr/include/x86_64-linux-gnu/c++/13/bits/stdc++.h:53:
/usr/include/c++/13/bits/stl_vector.h:133:14: note: called from here
  133 |       struct _Vector_impl
      |              ^~~~~~~~~~~~