Submission #1022040

#TimeUsernameProblemLanguageResultExecution timeMemory
1022040huutuanFlooding Wall (BOI24_wall)C++14
100 / 100
3851 ms237212 KiB
#include<bits/stdc++.h> using namespace std; #define int long long const int mod=1e9+7, N=1e6+10; int power2[N], invpower2[N]; struct Node{ int len, l, r, lr, lazyl, lazyr; Node (){ len=lazyl=lazyr=0; l=r=lr=0; } Node operator+(const Node &b){ Node ans; ans.len=len+b.len; ans.l=(l+b.l)%mod; ans.r=(r+b.r)%mod; ans.lr=(lr+b.lr)%mod; return ans; } int get_l(){ return (mod-(l-len+mod)%mod)%mod; } int get_r(){ return (mod-(r-len+mod)%mod)%mod; } int get_lr(){ return (lr-l-r+len+mod+mod)%mod; } }; struct SegmentTree{ int n; vector<Node> t; void init(int _n){ n=_n; t.assign(4*n+1, Node()); } void build(int k, int l, int r, const vector<int> &vals){ if (l==r){ t[k].len=vals[r]-vals[l-1]; t[k].l=t[k].len; t[k].r=t[k].len; t[k].lr=t[k].len; return; } int mid=(l+r)>>1; build(k<<1, l, mid, vals); build(k<<1|1, mid+1, r, vals); t[k]=t[k<<1]+t[k<<1|1]; } void apply(int k, int lazyl, int lazyr){ if (lazyl){ int x=lazyl>0?power2[lazyl]:invpower2[-lazyl]; t[k].l=1ll*t[k].l*x%mod; t[k].lr=1ll*t[k].lr*x%mod; t[k].lazyl+=lazyl; } if (lazyr){ int x=lazyr>0?power2[lazyr]:invpower2[-lazyr]; t[k].r=1ll*t[k].r*x%mod; t[k].lr=1ll*t[k].lr*x%mod; t[k].lazyr+=lazyr; } } void push(int k){ apply(k<<1, t[k].lazyl, t[k].lazyr); apply(k<<1|1, t[k].lazyl, t[k].lazyr); t[k].lazyl=t[k].lazyr=0; } void update(int k, int l, int r, int L, int R, int lazyl, int lazyr){ if (r<L || R<l) return; if (L<=l && r<=R){ apply(k, lazyl, lazyr); return; } push(k); int mid=(l+r)>>1; update(k<<1, l, mid, L, R, lazyl, lazyr); update(k<<1|1, mid+1, r, L, R, lazyl, lazyr); t[k]=t[k<<1]+t[k<<1|1]; } Node get(int k, int l, int r, int L, int R){ if (r<L || R<l) return t[0]; if (L<=l && r<=R) return t[k]; push(k); int mid=(l+r)>>1; return get(k<<1, l, mid, L, R)+get(k<<1|1, mid+1, r, L, R); } } st; int n, a[N], b[N]; int pf[N], sf[N]; int32_t main(){ ios_base::sync_with_stdio(false); cin.tie(nullptr); power2[0]=1; for (int i=1; i<N; ++i) power2[i]=power2[i-1]*2%mod; invpower2[0]=1; invpower2[1]=(mod+1)/2; for (int i=2; i<N; ++i) invpower2[i]=invpower2[i-1]*invpower2[1]%mod; cin >> n; vector<int> vals{0}; for (int i=1; i<=n; ++i) cin >> a[i], vals.push_back(a[i]); for (int i=1; i<=n; ++i) cin >> b[i], vals.push_back(b[i]); sort(vals.begin(), vals.end()); vals.resize(unique(vals.begin(), vals.end())-vals.begin()); st.init((int)vals.size()-1); st.build(1, 1, st.n, vals); for (int i=1; i<=n; ++i){ a[i]=lower_bound(vals.begin(), vals.end(), a[i])-vals.begin(); b[i]=lower_bound(vals.begin(), vals.end(), b[i])-vals.begin(); st.update(1, 1, st.n, min(a[i], b[i])+1, max(a[i], b[i]), 0, -1); pf[i]=max(pf[i-1], min(a[i], b[i])); } for (int i=n; i>=1; --i) sf[i]=max(sf[i+1], min(a[i], b[i])); int ans=0; for (int i=1; i<=n; ++i){ st.update(1, 1, st.n, min(a[i], b[i])+1, max(a[i], b[i]), 0, 1); if (i!=1 && i!=n){ int t1=pf[i-1], t2=sf[i+1]; { int l=a[i], r=min(t1, t2); if (l<r){ ans=(ans+(vals[r]-vals[l])*power2[n-1])%mod; } } { int l=max(a[i], t1), r=t2; if (l<r){ ans=(ans+st.get(1, 1, st.n, l+1, r).get_l()*power2[n-1])%mod; } } { int l=max(a[i], t2), r=t1; if (l<r){ ans=(ans+st.get(1, 1, st.n, l+1, r).get_r()*power2[n-1])%mod; } } { int l=max({a[i], t1, t2}), r=st.n; if (l<r){ ans=(ans+st.get(1, 1, st.n, l+1, r).get_lr()*power2[n-1])%mod; } } { int l=b[i], r=min(t1, t2); if (l<r){ ans=(ans+(vals[r]-vals[l])*power2[n-1])%mod; } } { int l=max(b[i], t1), r=t2; if (l<r){ ans=(ans+st.get(1, 1, st.n, l+1, r).get_l()*power2[n-1])%mod; } } { int l=max(b[i], t2), r=t1; if (l<r){ ans=(ans+st.get(1, 1, st.n, l+1, r).get_r()*power2[n-1])%mod; } } { int l=max({b[i], t1, t2}), r=st.n; if (l<r){ ans=(ans+st.get(1, 1, st.n, l+1, r).get_lr()*power2[n-1])%mod; } } } st.update(1, 1, st.n, min(a[i], b[i])+1, max(a[i], b[i]), -1, 0); } cout << ans << '\n'; return 0; }
#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...