Submission #1014272

#TimeUsernameProblemLanguageResultExecution timeMemory
1014272hengliaoFlooding Wall (BOI24_wall)C++17
58 / 100
2894 ms87636 KiB
#pragma GCC optimize("Ofast") #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{ vector<int> tree, lazy; int treelen; void init(int siz){ treelen=siz+1; while(__builtin_popcount(treelen)!=1){ treelen++; } tree=vector<int>(2*treelen, 0); lazy=vector<int>(2*treelen, 1); } void push(ll idx, ll low, ll high){ if(low!=high){ lazy[2*idx]=((long long) lazy[2*idx]*lazy[idx])%mod; //lazy[2*idx]%=mod; lazy[2*idx+1]=((long long) lazy[2*idx+1]*lazy[idx])%mod; } } void check(ll idx, ll low, ll high){ if(lazy[idx]==1) return; tree[idx]=((long long) tree[idx]*lazy[idx])%mod; //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]=((long long) lazy[idx]*val)%mod; //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]; tree[idx]%=mod; } 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); re%=mod; 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]; tree[idx]%=mod; } 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:189:12: warning: unused variable 'pre' [-Wunused-variable]
  189 |         ll pre=1;
      |            ^~~
Main.cpp:248:12: warning: unused variable 'pre' [-Wunused-variable]
  248 |         ll pre=1;
      |            ^~~
Main.cpp:321:20: warning: unused variable 'val2' [-Wunused-variable]
  321 |                 ll val2=it2.F;
      |                    ^~~~
Main.cpp:317:12: warning: unused variable 'pre' [-Wunused-variable]
  317 |         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...