Submission #1343798

#TimeUsernameProblemLanguageResultExecution timeMemory
1343798StefanSebezConstellation 3 (JOI20_constellation3)C++20
100 / 100
379 ms71888 KiB
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second 
#define pb push_back
#define ll long long
template<typename T1,typename T2>void chmn(T1 &x,const T2 &y){x=x<y?x:y;}
template<typename T1,typename T2>void chmx(T1 &x,const T2 &y){x=x>y?x:y;}
const int N=2e5+50,lg=18;
int n,H[N],m;
array<int,3>a[N];
int Lv[N],Rv[N];
ll dpl[N],dpr[N];
vector<array<int,3>>ev[N][2];
int MX[N][lg+1],LOG[N];
int MAX(int l,int r){if(l>r)return 0;int i=LOG[r-l+1];return max(MX[l][i],MX[r-(1<<i)+1][i]);}
vector<int>E[2][N];
int in[2][N],out[2][N],tajm[2];
struct BIT{
    ll T[N];
    void Update(int i,ll x){for(;i<N;i+=i&-i)T[i]+=x;}
    ll Get(int i){ll x=0;for(;i>=1;i-=i&-i)x+=T[i];return x;}
    ll Get(int l,int r){return Get(r)-Get(l-1);}
}bt[2];
void DFS(int u,int ind){
    in[ind][u]=++tajm[ind];
    for(auto i:E[ind][u])DFS(i,ind);
    out[ind][u]=tajm[ind];
}
int main(){
    for(int i=2;i<N;i++)LOG[i]=LOG[i>>1]+1;
    scanf("%i",&n);
    for(int i=1;i<=n;i++)scanf("%i",&H[i]);
    scanf("%i",&m);
    for(int i=1;i<=m;i++)scanf("%i%i%i",&a[i][0],&a[i][1],&a[i][2]);
    H[0]=H[n+1]=n+1;
    for(int i=0;i<=n+1;i++)Lv[i]=0,Rv[i]=n+1;
    vector<int>mono;
    for(int i=1;i<=n;i++){
        while(!mono.empty()&&H[mono.back()]<H[i])mono.pop_back();
        if(!mono.empty())Lv[i]=mono.back();
        mono.pb(i);
    }
    mono.clear();
    for(int i=n;i>=1;i--){
        while(!mono.empty()&&H[mono.back()]<H[i])mono.pop_back();
        if(!mono.empty())Rv[i]=mono.back();
        mono.pb(i);
    }
    //for(int i=0;i<=n+1;i++)printf("%i ",Lv[i]);printf("\n");
    //for(int i=0;i<=n+1;i++)printf("%i ",Rv[i]);printf("\n");
    for(int i=0;i<=n+1;i++)MX[i][0]=H[i];
    for(int j=0;j<lg;j++)for(int i=0;i<=n+1;i++)if(i+(1<<j)<=n+1){
        MX[i][j+1]=max(MX[i][j],MX[i+(1<<j)][j]);
    }
    for(int i=0;i<=n+1;i++){
        if(i!=0)E[0][Lv[i]].pb(i);
        if(i!=n+1)E[1][Rv[i]].pb(i);
    }
    DFS(0,0);
    DFS(n+1,1);
    //for(int i=0;i<=n+1;i++)printf("%i->%i\n",i,Lv[i]);
    //for(int i=0;i<=n+1;i++){printf("%i: ",i);for(auto j:E[0][i])printf("%i ",j);printf("\n");}
    //for(int i=0;i<=n+1;i++)printf("%i: in=%i out=%i\n",i,in[0][i],out[0][i]);
    for(int i=1;i<=m;i++){
        auto [x,y,c]=a[i];
        int l=0,r=x,L=x,R=x;
        while(l<=r){
            int mid=l+r>>1;
            if(MAX(mid,x)>=y){L=mid,l=mid+1;}
            else r=mid-1;
        }
        l=x,r=n+1;
        while(l<=r){
            int mid=l+r>>1;
            if(MAX(x,mid)>=y){R=mid,r=mid-1;}
            else l=mid+1;
        }
        if(H[L]<=H[R])ev[L][1].pb({x,y,c});
        if(H[L]>=H[R])ev[R][0].pb({x,y,c});
    }
    vector<int>ids[n+5];
    for(int i=0;i<=n+1;i++)ids[H[i]].pb(i);
    vector<int>ord(n+2);
    iota(ord.begin(),ord.end(),0);
    sort(ord.begin(),ord.end(),[&](int i,int j){return H[i]<H[j];});
    for(auto I:ord){
        int L=Lv[I],R=Rv[I];
        int mx=MAX(I+1,R-1);
        if(mx>0){
            int l=lower_bound(ids[mx].begin(),ids[mx].end(),I+1)-ids[mx].begin();
            int r=upper_bound(ids[mx].begin(),ids[mx].end(),R-1)-ids[mx].begin()-1;
            for(int i=l;i<=r;i++)dpr[I]+=dpl[ids[mx][i]];
            dpr[I]+=dpr[ids[mx][r]];
            //for(int i=I+1;i<=R-1;i++)if(H[i]==mx)dpr[I]+=dpl[i];
            //for(int i=R-1;i>=I+1;i--)if(H[i]==mx){dpr[I]+=dpr[i];break;}
        }
        mx=MAX(L+1,I-1);
        if(mx>0){
            int l=lower_bound(ids[mx].begin(),ids[mx].end(),L+1)-ids[mx].begin();
            int r=upper_bound(ids[mx].begin(),ids[mx].end(),I-1)-ids[mx].begin()-1;
            for(int i=l;i<=r;i++)dpl[I]+=dpl[ids[mx][i]];
            dpl[I]+=dpr[ids[mx][r]];
            //for(int i=L+1;i<=I-1;i++)if(H[i]==mx)dpl[I]+=dpl[i];
            //for(int i=I-1;i>=L+1;i--)if(H[i]==mx){dpl[I]+=dpr[i];break;}
        }
        for(auto [x,y,c]:ev[I][1]){
            //printf("[%i %i]: %i %i %i\n",I,R,x,y,c);
            ll sum=c;
            sum+=bt[0].Get(in[0][x])-bt[0].Get(in[0][I]);
            //ll X=bt[1].Get(x)-bt[1].Get(R);
            //ll Y=0;for(int i=x;i<R;i=Rv[i])Y+=dpr[i];
            //printf("%lld %lld %lld %lld\n",X,Y,bt[1].Get(x),bt[1].Get(R));
            //for(int i=x;i>I;i=Lv[i])sum+=dpl[i];
            sum+=bt[1].Get(in[1][x])-bt[1].Get(in[1][R]);
            //for(int i=x;i<R;i=Rv[i])sum+=dpr[i];
            chmx(dpr[I],sum);
        }
        for(auto [x,y,c]:ev[I][0]){
            //printf("[%i %i]: %i %i %i\n",L,I,x,y,c);
            ll sum=c;
            sum+=bt[0].Get(in[0][x])-bt[0].Get(in[0][L]);
            //for(int i=x;i>L;i=Lv[i])sum+=dpl[i];
            sum+=bt[1].Get(in[1][x])-bt[1].Get(in[1][I]);
            //for(int i=x;i<I;i=Rv[i])sum+=dpr[i];
            chmx(dpl[I],sum);
        }
        bt[0].Update(in[0][I],dpl[I]);
        bt[0].Update(out[0][I]+1,-dpl[I]);
        bt[1].Update(in[1][I],dpr[I]);
        bt[1].Update(out[1][I]+1,-dpr[I]);
    }
    ll res=0;
    for(int i=1;i<=m;i++)res+=a[i][2];
    res-=dpr[0];
    printf("%lld\n",res);
    return 0;
}

Compilation message (stderr)

constellation3.cpp: In function 'int main()':
constellation3.cpp:32:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   32 |     scanf("%i",&n);
      |     ~~~~~^~~~~~~~~
constellation3.cpp:33:31: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   33 |     for(int i=1;i<=n;i++)scanf("%i",&H[i]);
      |                          ~~~~~^~~~~~~~~~~~
constellation3.cpp:34:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   34 |     scanf("%i",&m);
      |     ~~~~~^~~~~~~~~
constellation3.cpp:35:31: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   35 |     for(int i=1;i<=m;i++)scanf("%i%i%i",&a[i][0],&a[i][1],&a[i][2]);
      |                          ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...