Submission #1014252

#TimeUsernameProblemLanguageResultExecution timeMemory
1014252hengliaoFlooding Wall (BOI24_wall)C++17
58 / 100
4493 ms136928 KiB
#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{
    vll tree, lazy;
    ll treelen;

    void init(ll siz){
        treelen=siz+1;
        while(__builtin_popcount(treelen)!=1){
            treelen++;
        }
        tree=vll(2*treelen, 0);
        lazy=vll(2*treelen, 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){
        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;
        update1(2*idx, low, mid, qlow, qhigh, val);
        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;
        return getsum1(2*idx, low, mid, qlow, qhigh)+
        getsum1(2*idx+1, mid+1, high, qlow, qhigh);
    }

    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;
        setto1(2*idx, low, mid, qlow, qhigh, val);
        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<63;i++){
        if(b&(1LL<<i)){
            re*=a;
            re%=mod;
        }
        a*=a;
        a%=mod;
    }
    return re;
}

ll inv(ll a){
    return pw(a, mod-2);
}

ll seg[mxN];
ll lef[mxN][2];
ll rig[mxN][2];
bool good[mxN][2];
ll n;
ll a[mxN][2];
vector<pair<ll, pll>> v;
segtree SEG, SEG2, SEG3, SEG4;
ll inv2;

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(2*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.setto(2*n, 1);
    SEG3.setto(2*n+1, 1);
    for(ll i=n-1;i>=0;i--){
        SEG3.setto(2*i, pre);
        SEG3.setto(2*i+1, pre);
        pre*=2;
        pre%=mod;
    }
    sort(v.begin(), v.end(), compare);
    ll ans=0;
    for(auto &it:v){
        ll val=it.F;
        ll id=it.S.F;
        ll id2=it.S.S;
        ll pre=1;
        ll 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;
            cur*=inv(seg[id]);
            cur%=mod;
        }
        ans+=cur*val;
        ans%=mod;
        ans+=(((val*((SEG3.getsum(0, 0)*inv(SEG3.getsum(2*id, 2*id)))%mod)))%mod)
        *SEG3.getsum(2*(id+1), 2*(id+1));
        ans%=mod;
        ll tep=pw(2, id)*SEG3.getsum(2*(id+1), 2*(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(0, 2*id+1, inv2);
            if(id>0){
                SEG.update(0, 2*id-1, inv2);
                SEG2.update(0, 2*id-1, inv2);
            }
        }
        else{
            SEG3.update(0, 2*id+1, 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(2*n+10);
    pre=2;
    SEG3.setto(2*n, 1);
    SEG3.setto(2*n+1, 1);
    for(ll i=0;i<n;i++){
        SEG3.setto(2*i, pre);
        SEG3.setto(2*i+1, pre);
        pre*=2;
        pre%=mod;
    }
    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){
        ll val=it.F;
        ll id=it.S.F;
        ll id2=it.S.S;
        ll pre=1;
        ll 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;
            cur*=inv(seg[id]);
            cur%=mod;
        }
        ans+=cur*val;
        ans%=mod;
        ll tep;
        if(id>0) tep=pw(2, n-id-1)*SEG3.getsum(2*(id-1), 2*(id-1));
        else tep=pw(2, 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(2*id, 2*n-1, 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(2*id, 2*n-1, 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(2*n+10);
    SEG4.init(2*n+10);
    pre=2;
    SEG3.setto(2*n, 1);
    SEG3.setto(2*n+1, 1);
    for(ll i=0;i<n;i++){
        SEG3.setto(2*i, pre);
        SEG3.setto(2*i+1, pre);
        pre*=2;
        pre%=mod;
    }
    pre=2;
    SEG4.setto(2*n, 1);
    SEG4.setto(2*n+1, 1);
    for(ll i=n-1;i>=0;i--){
        SEG4.setto(2*i, pre);
        SEG4.setto(2*i+1, pre);
        pre*=2;
        pre%=mod;
    }
    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;
    for(auto &it:v){
        ll val=it.F;
        ll id=it.S.F;
        ll id2=it.S.S;
        ll pre=1;
        ll cur=0;
        if(val!=preval){
            for(auto &it2:waiting){
                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(0, 2*id23+1, inv2);
                    
                }
                else{
                    SEG4.update(0, 2*id23+1, 0);
                    
                }
            }
            waiting.clear();
        }
        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;
            cur*=inv(seg[id]);
            cur%=mod;
        }
        ans-=cur*val;
        ans%=mod;
        if(ans<0) ans+=mod;
        ll tep;
        if(id>0) tep=SEG4.getsum(2*(id+1), 2*(id+1))*SEG3.getsum(2*(id-1), 2*(id-1));
        else tep=SEG4.getsum(2*(id+1), 2*(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(2*id, 2*n-1, 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(2*id, 2*n-1, 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]*pw(2, 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);

	solve();
	return 0;
}

Compilation message (stderr)

Main.cpp: In function 'void solve()':
Main.cpp:179:12: warning: unused variable 'pre' [-Wunused-variable]
  179 |         ll pre=1;
      |            ^~~
Main.cpp:238:12: warning: unused variable 'pre' [-Wunused-variable]
  238 |         ll pre=1;
      |            ^~~
Main.cpp:311:20: warning: unused variable 'val2' [-Wunused-variable]
  311 |                 ll val2=it2.F;
      |                    ^~~~
Main.cpp:307:12: warning: unused variable 'pre' [-Wunused-variable]
  307 |         ll pre=1;
      |            ^~~
#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...