Submission #1351092

#TimeUsernameProblemLanguageResultExecution timeMemory
1351092kokokaiConstellation 3 (JOI20_constellation3)C++20
100 / 100
261 ms90840 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define fi first
#define se second
#define task "text"
const int N = 2e5+5;
const int LG = 19;
struct point{
    int x,y,c;
}pts[N];
struct node{
    int l,r,id;
    bool operator < (const node &oth) const{
        if(l == oth.l) return r < oth.r;
        return l < oth.l;
    }
};
set<node> s;
int a[N];
int n,m;
int tin[N],tout[N],minn[N][LG],par[N],lef[N],rig[N],timer;
vector<int> son[N];
vector<pair<int,int>> eve[N];
vector<point> ptsof[N];
int getmin(int l,int r){
    int lg=log2(r-l+1);
    int le=minn[l][lg];
    int ri=minn[r-(1<<lg)+1][lg];
    return (a[le] <= a[ri] ? le:ri);
}
int root;
void buildtree(int l,int r,int prehi=0,int pare=0){
    if(l>r) return;
    int mid=getmin(l,r);
    if(pare == 0) root=mid;
    int low=prehi+1;
    lef[mid]=l;
    rig[mid]=r;
    int high=a[mid];
    if(low <= high){
        eve[low].push_back({mid,1});
        eve[high+1].push_back({mid,-1});
    }
    par[mid]=pare;
    //cerr<<pare<<' '<<mid<<'\n';
    son[pare].push_back(mid);
    if(l == r) return;
    buildtree(l,mid-1,a[mid],mid);
    buildtree(mid+1,r,a[mid],mid);
}
void dfs(int u,int p){
    tin[u]=tout[u]=++timer;
    for(int v:son[u]){
        if(v==p) continue;
        dfs(v,u);
    }
    tout[u]=timer;
}
struct segtree{
    ll st[4*N],lz[4*N];
    void down(int id,int l,int r){
        if(lz[id]==0) return;
        ll t=lz[id];
        lz[id<<1]+=t;
        lz[id<<1|1]+=t;
        st[id<<1]+=t;
        st[id<<1|1]+=t;
        lz[id]=0;
        return;
    }
    void update(int id,int l,int r,int u,int v,ll val){
        if(r<u || v<l) return;
        if(u<=l && r<=v){
            st[id]+=val;
            lz[id]+=val;
            return;
        }
        int mid=(l+r)>>1;
        down(id,l,r);
        update(id<<1,l,mid,u,v,val);
        update(id<<1|1,mid+1,r,u,v,val);
    }
    ll get(int id,int l,int r,int p){
        if(l==r) return st[id];
        int mid=(l+r)>>1;
        down(id,l,r);
        if(mid<p) return get(id<<1|1,mid+1,r,p);
        else return get(id<<1,l,mid,p);
    }
}st;
ll ret=0;
ll dp[N];
ll calc(int u,int p){
    //cerr<<u<<'\n';
    ll sum=0;
    for(int v:son[u]){
        if(v==p) continue;
        sum += calc(v,u);
    }
    for(int v:son[u]){
        if(v==p) continue;
        ll rem=sum-dp[v];
        st.update(1,1,n,tin[v],tout[v],rem);
    }
    ll ans=sum;

    for(auto p:ptsof[u]){
        //cerr<<u<<' '<<p.x<<' '<<p.y<<' '<<p.c<<'\n';
        int x=p.x;
        ll c=p.c;
        if(x == u) ans=max(ans,sum+c);
        else{
            ll re=st.get(1,1,n,tin[x]);
            ll res=c+re;
            for(int v:son[x]) res+=dp[v];
            //if(u == 2 && c == 10) cerr<<res<<'\n';
            ans=max(ans,res);
        }
    }
    dp[u]=ans;
    return dp[u];
}
int main(){
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    if(fopen(task".inp","r")){
        freopen(task".inp","r",stdin);
    }
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        a[i]=n-a[i];
    }
    for(int i=1;i<=n;i++) minn[i][0]=i;
    for(int lg=1;lg<LG;lg++){
        for(int i=1;i+(1<<lg)-1<=n;i++){
            int l=minn[i][lg-1];
            int r=minn[i+(1<<(lg-1))][lg-1];
            minn[i][lg] = (a[l] <= a[r] ? l:r);
        }
    }
    cin>>m;
    for(int i=1;i<=m;i++){
        cin>>pts[i].x>>pts[i].y>>pts[i].c;
        pts[i].y=n-pts[i].y+1;
    }
    buildtree(1,n);

    sort(pts+1,pts+1+m,[&](point a,point b){
        return a.y < b.y;
    });
    int j=1;
    for(int i=1;i<=n;i++){
        for(auto &[id,add]:eve[i]){
            //cerr<<lef[id]<<' '<<rig[id]<<' '<<add<<'\n';
            if(add == 1) s.insert({lef[id],rig[id],id});
            else s.erase(s.find({lef[id],rig[id],id}));
        }
        while(j<=m && pts[j].y <= i){
            auto it=s.upper_bound({pts[j].x,(int)1e9,(int)1e9});
            if(it != s.begin()){
                --it;
                ptsof[it->id].push_back(pts[j]);
               // cerr<<pts[j].c<<' '<<it->id<<'\n';
            }
            //cerr<<pts[j].x<<'\n';
            j++;
        }
    }
    ll sum=0;
    for(int i=1;i<=m;i++) sum+=pts[i].c;
    dfs(root,0);
    cout<<sum-calc(root,0)<<'\n';;
    //cout<<dp[5]<<'\n';
}





Compilation message (stderr)

constellation3.cpp: In function 'int main()':
constellation3.cpp:127:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  127 |         freopen(task".inp","r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...