Submission #1014310

#TimeUsernameProblemLanguageResultExecution timeMemory
1014310hengliaoFlooding Wall (BOI24_wall)C++17
58 / 100
4155 ms235868 KiB
#pragma GCC optimize("Ofast") #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 init2(){ 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); } 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, 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=pw2[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.init2(); SEG2.init2(); SEG3.init2(); 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=pw2[n-id-1]*SEG3.getsum(2*(id-1), 2*(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(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.init2(); SEG2.init2(); SEG3.init2(); 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'; if(n>=10005) return; 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:195:12: warning: unused variable 'pre' [-Wunused-variable]
  195 |         ll pre=1;
      |            ^~~
Main.cpp:254:12: warning: unused variable 'pre' [-Wunused-variable]
  254 |         ll pre=1;
      |            ^~~
Main.cpp:327:20: warning: unused variable 'val2' [-Wunused-variable]
  327 |                 ll val2=it2.F;
      |                    ^~~~
Main.cpp:323:12: warning: unused variable 'pre' [-Wunused-variable]
  323 |         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...