Submission #1014357

#TimeUsernameProblemLanguageResultExecution timeMemory
1014357hengliaoFlooding Wall (BOI24_wall)C++17
70 / 100
5062 ms182028 KiB
#pragma GCC optimize("Ofast,unroll-loops")
#pragma GCC target("popcnt")
#include<bits/stdc++.h>
#include <chrono>
#include <random>
using namespace std;
 
#define F first
#define S second
#define pb push_back
#define vll vector<ll>
#define pll pair<ll, ll>
typedef long long ll;
 
const ll mod=1e9+7;
const ll mxN=5e5+5;
 
struct segtree{
    ll tree[8*mxN];
    ll lazy[8*mxN];
    ll treelen;
 
    void init(ll siz){
        treelen=siz+1;
        while(__builtin_popcount(treelen)!=1){
            treelen++;
        }
        memset(tree, 0, sizeof(tree));
        for(ll i=0;i<2*treelen;i++) lazy[i]=1;
    }
 
    void push(ll idx, ll low, ll high){
        if(low!=high){
            lazy[2*idx]*=lazy[idx];
            lazy[2*idx]%=mod;
            lazy[2*idx+1]*=lazy[idx];
            lazy[2*idx+1]%=mod;
        }
    }
 
    void check(ll idx, ll low, ll high){
        if(lazy[idx]==1) return;
        tree[idx]*=lazy[idx];
        tree[idx]%=mod;
        push(idx, low, high);
        lazy[idx]=1;
    }
 
    void update1(ll idx, ll low, ll high, ll qlow, ll qhigh, ll val){
        //check(idx, low, high);
        if(low>=qlow && high<=qhigh){
            lazy[idx]*=val;
            lazy[idx]%=mod;
            check(idx, low, high);
            return;
        }
        if(low>qhigh || high<qlow){
            return;
        }
        ll mid=(low+high)/2;
        check(2*idx, low, mid);
        if(qlow<=mid) update1(2*idx, low, mid, qlow, qhigh, val);
        check(2*idx+1, mid+1, high);
        if(qhigh>=mid+1) update1(2*idx+1, mid+1, high, qlow, qhigh, val);
        tree[idx]=tree[2*idx]+tree[2*idx+1];
    }
 
    ll getsum1(ll idx, ll low, ll high, ll qlow, ll qhigh){
        check(idx, low, high);
        if(low>=qlow && high<=qhigh){
            return tree[idx];
        }
        if(low>qhigh || high<qlow){
            return 0LL;
        }
        ll mid=(low+high)/2;
        ll re=0;
        if(qlow<=mid) re+=getsum1(2*idx, low, mid, qlow, qhigh);
        if(qhigh>=mid+1) re+=getsum1(2*idx+1, mid+1, high, qlow, qhigh);
        return re;
    }
 
    void setto1(ll idx, ll low, ll high, ll qlow, ll qhigh, ll val){
        //check(idx, low, high);
        if(low>=qlow && high<=qhigh){
            tree[idx]=val;
            tree[idx]%=mod;
            //check(idx, low, high);
            return;
        }
        if(low>qhigh || high<qlow){
            return;
        }
        ll mid=(low+high)/2;
        check(2*idx, low, mid);
        if(qlow<=mid) setto1(2*idx, low, mid, qlow, qhigh, val);
        check(2*idx+1, mid+1, high);
        if(qhigh>=mid+1) setto1(2*idx+1, mid+1, high, qlow, qhigh, val);
        tree[idx]=tree[2*idx]+tree[2*idx+1];
    }
 
    void update(ll qlow, ll qhigh, ll val){
        update1(1, 0, treelen-1, qlow, qhigh, val);
    }
 
    ll getsum(ll qlow, ll qhigh){
        return getsum1(1, 0, treelen-1, qlow, qhigh);
    }
 
    void setto(ll idx, ll val){
        setto1(1, 0, treelen-1, idx, idx, val);
    }
};


 
ll pw(ll a, ll b){
    ll re=1;
    a%=mod;
    for(ll i=0;i<32;i++){
        if(b&(1LL<<i)){
            re*=a;
            re%=mod;
        }
        a*=a;
        a%=mod;
    }
    return re;
}
 
ll inv(ll a){
    return pw(a, mod-2);
}

struct BIT{
    ll tree[2*mxN];
    ll siz;

    void init(ll sz){
        siz=sz+1;
        for(ll i=1;i<siz;i++){
            tree[i]=1;
        }
    }

    void update(ll idx, ll val){
        idx++;
        for(;idx<siz;idx+=(idx&-idx)){
            tree[idx]*=val;
            tree[idx]%=mod;
        }
    }

    ll getpre(ll idx){
        idx++;
        ll re=1;
        for(;idx>0;idx-=(idx&-idx)){
            re*=tree[idx];
            re%=mod;
        }
        return re;
    }

    ll getrng(ll a, ll b){
        if(a==0) return getpre(b);
        return (getpre(b)*inv(getpre(a-1)))%mod;
    }
};
 
ll seg[mxN];
ll lef[mxN][2];
ll rig[mxN][2];
ll pw2[mxN];
bool good[mxN][2];
ll n;
ll a[mxN][2];
vector<pair<ll, pll>> v;
segtree SEG, SEG2;
BIT SEG3, SEG4;
ll inv2;
ll val, id, id2, pre, cur;
 
bool compare(pair<ll, pll> &a, pair<ll, pll> &b){
    if(a.F!=b.F){
        return a.F>b.F;
    }
    return a.S.F<b.S.F;
}
 
bool compare2(pair<ll, pll> &a, pair<ll, pll> &b){
    if(a.F!=b.F){
        return a.F>b.F;
    }
    return a.S.F>b.S.F;
}
 
void solve(){
    memset(good, 0, sizeof(good));
	cin>>n;
    SEG.init(2*n+10);
    SEG2.init(2*n+10);
    SEG3.init(n+10);
    for(ll i=0;i<n;i++){
        cin>>a[i][0];
    }
    for(ll i=0;i<n;i++){
        cin>>a[i][1];
    }
    for(ll i=0;i<n;i++){
        v.pb({a[i][0], {i, 0}});
        v.pb({a[i][1], {i, 1}});
        seg[i]=2;
    }
    ll pre=2;
    SEG3.update(n, 1);
    for(ll i=n-1;i>=0;i--){
        SEG3.update(i, 2);
    }
    sort(v.begin(), v.end(), compare);
    ll ans=0;
    for(auto &it:v){
        val=it.F;
        id=it.S.F;
        id2=it.S.S;
        pre=1;
        cur=0;
        if(id>0){
            cur=id*SEG2.getsum(0, 2*id-1);
            cur%=mod;
            if(cur<0) cur+=mod;
            cur-=SEG.getsum(0, 2*id-1);
            cur%=mod;
            if(cur<0) cur+=mod;
            if(seg[id]==2){
                cur*=inv2;
                cur%=mod;
            }
        }
        ans+=cur*val;
        ans%=mod;
        ans+=((val*(SEG3.getrng(0, n-1))%mod)*inv(seg[id]));
        ans%=mod;
        ll tep=pw2[id]*SEG3.getrng(0, n-id-2);
        tep%=mod;
        SEG2.setto(2*id+id2, tep);
        SEG.setto(2*id+id2, (id*tep)%mod);
        seg[id]--;
        if(seg[id]==1){
            SEG3.update(n-1-id, inv2);
            if(id>0){
                SEG.update(0, 2*id-1, inv2);
                SEG2.update(0, 2*id-1, inv2);
            }
        }
        else{
            SEG3.update(n-1-id, 0);
            if(id>0){
                SEG.update(0, 2*id-1, 0);
                SEG2.update(0, 2*id-1, 0);
            }
        }
    }
    //if(n>=10005) return;
    SEG.init(2*n+10);
    SEG2.init(2*n+10);
    SEG3.init(n+10);
    pre=2;
    SEG3.update(n, 1);
    for(ll i=0;i<n;i++){
        SEG3.update(i, 2);
    }
    sort(v.begin(), v.end(), compare2);
    memset(good, 0, sizeof(good));
    for(ll i=0;i<n;i++){
        seg[i]=2;
    }
    for(auto &it:v){
        val=it.F;
        id=it.S.F;
        id2=it.S.S;
        pre=1;
        cur=0;
        if(id<n-1){
            cur-=id*SEG2.getsum(2*(id+1), 2*n-1);
            cur%=mod;
            if(cur<0) cur+=mod;
            cur+=SEG.getsum(2*(id+1), 2*n-1);
            cur%=mod;
            if(cur<0) cur+=mod;
            if(seg[id]==2){
                cur*=inv2;
                cur%=mod;
            }
        }
        ans+=cur*val;
        ans%=mod;
        ll tep;
        if(id>0) tep=pw2[n-id-1]*SEG3.getrng(0, id-1);
        else tep=pw2[n-id-1];
        tep%=mod;
        SEG2.setto(2*id+id2, tep);
        SEG.setto(2*id+id2, (id*tep)%mod);
        seg[id]--;
        if(seg[id]==1){
            SEG3.update(id, inv2);
            if(id<n-1){
                SEG.update(2*(id+1), 2*n-1, inv2);
                SEG2.update(2*(id+1), 2*n-1, inv2);
            }
        }
        else{
            SEG3.update(id, 0);
            if(id<n-1){
                SEG.update(2*(id+1), 2*n-1, 0);
                SEG2.update(2*(id+1), 2*n-1, 0);
            }
        }
    }
    SEG.init(2*n+10);
    SEG2.init(2*n+10);
    SEG3.init(n+10);
    SEG4.init(n+10);
    pre=2;
    SEG3.update(n, 1);
    for(ll i=0;i<n;i++){
        SEG3.update(i, 2);
    }
    pre=2;
    SEG4.update(n, 1);
    for(ll i=n-1;i>=0;i--){
        SEG4.update(i, 2);
    }
    memset(good, 0, sizeof(good));
    for(ll i=0;i<n;i++){
        seg[i]=2;
    }
    ll preval=0;
    vector<pair<ll, pll>> waiting;
    //if(n>=10005) return;
    ll pt=0;
    pair<ll, pll> it2;
    for(auto &it:v){
        val=it.F;
        id=it.S.F;
        id2=it.S.S;
        pre=1;
        cur=0;
        if(val!=preval){
            for(;pt<waiting.size();pt++){
                it2=waiting[pt];
                ll val2=it2.F;
                ll id23=it2.S.F;
                ll id22=it2.S.S;
                SEG2.setto(2*id23+id22, 0);
                SEG.setto(2*id23+id22, 0);
                if(seg[id23]==1){
                    SEG4.update(n-1-id23, inv2);
                }
                else{
                    SEG4.update(n-1-id23, 0);
                }
            }
        }
        if(id<n-1){
            cur-=id*SEG2.getsum(2*(id+1), 2*n-1);
            cur%=mod;
            if(cur<0) cur+=mod;
            cur+=SEG.getsum(2*(id+1), 2*n-1);
            cur%=mod;
            if(cur<0) cur+=mod;
            if(seg[id]==2){
                cur*=inv2;
                cur%=mod;
            }
        }
        ans-=cur*val;
        ans%=mod;
        if(ans<0) ans+=mod;
        ll tep;
        if(id>0) tep=SEG4.getrng(0, n-id-2)*SEG3.getrng(0, id-1);
        else tep=SEG4.getrng(0, n-id-2);
        tep%=mod;
        SEG2.setto(2*id+id2, tep);
        SEG.setto(2*id+id2, (id*tep)%mod);
        seg[id]--;
        if(seg[id]==1){
            SEG3.update(id, inv2);
            if(id<n-1){
                SEG.update(2*(id+1), 2*n-1, inv2);
                SEG2.update(2*(id+1), 2*n-1, inv2);
            }
        }
        else{
            SEG3.update(id, 0);
            if(id<n-1){
                SEG.update(2*(id+1), 2*n-1, 0);
                SEG2.update(2*(id+1), 2*n-1, 0);
            }
        }
        preval=val;
        waiting.pb(it);
    }
    //cout<<ans<<'\n';
    for(ll i=0;i<n;i++){
        for(ll j=0;j<2;j++){
            ans-=a[i][j]*pw2[n-1];
            ans%=mod;
            if(ans<0) ans+=mod;
        }
    }
    cout<<ans<<'\n';
}
 
int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
 
    inv2=inv(2);
    pw2[0]=1;
    for(ll i=1;i<mxN;i++){
        pw2[i]=pw2[i-1]*2;
        pw2[i]%=mod;
    }
 
	solve();
	return 0;
}

Compilation message (stderr)

Main.cpp: In function 'void solve()':
Main.cpp:349:20: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<std::pair<long long int, std::pair<long long int, long long int> > >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  349 |             for(;pt<waiting.size();pt++){
      |                  ~~^~~~~~~~~~~~~~~
Main.cpp:351:20: warning: unused variable 'val2' [-Wunused-variable]
  351 |                 ll val2=it2.F;
      |                    ^~~~
Main.cpp:214:8: warning: variable 'pre' set but not used [-Wunused-but-set-variable]
  214 |     ll pre=2;
      |        ^~~
#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...