Submission #1014689

#TimeUsernameProblemLanguageResultExecution timeMemory
1014689hengliaoFlooding Wall (BOI24_wall)C++17
70 / 100
5084 ms182768 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>=mxN-10) 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...