Submission #827540

#TimeUsernameProblemLanguageResultExecution timeMemory
827540PagodePaivaFancy Fence (CEOI20_fancyfence)C++17
100 / 100
262 ms8992 KiB
#include<bits/stdc++.h> #define pii pair <int, int> #define fr first #define sc second #define N 100010 #define inf 1e18 #define int long long using namespace std; int n; int h[N], w[N]; int pref[N]; int mod = 1e9+7; struct Segtree{ pair <int,int> tree[4*N]; pair <int,int> join(pii a, pii b){ if(a.fr < b.fr) return a; if(a.fr > b.fr) return b; if(a.sc < b.sc) return a; return b; } void build(int l, int r, int node){ if(l == r){ tree[node] = {h[l], l}; return; } int mid = (l+r)/2; build(l, mid, 2*node); build(mid+1, r, 2*node+1); tree[node] = join(tree[2*node], tree[2*node+1]); return; } pair <int, int> query(int l, int r, int tl, int tr, int node){ if(tl > r or tr < l) return {inf, inf}; if(l <= tl and tr <= r) return tree[node]; int mid = (tl+tr)/2; return join(query(l, r, tl, mid, 2*node), query(l, r, mid+1, tr, 2*node+1)); } } seg; long long binpow(long long a, long long b, long long m) { a %= m; long long res = 1; while (b > 0) { if (b & (1ll)) res = res * a % m; a = a * a % m; b >>= (1ll); } return res; } int query(int l, int r, int minant){ int c = pref[r] - pref[l-1]; c %= mod; c += mod; c %= mod; int a = seg.query(l, r, 1, n, 1).fr; a %= mod; int res = (c-1)*(a-1); res %= mod; res *= c; res %= mod; res *= a; res %= mod; res *= binpow(4, mod-2, mod); res %= mod; int aux = (a+c-2)*a; aux %= mod; aux *= c; aux %= mod; aux *= binpow(2, mod-2, mod); aux %= mod; res += aux; res %= mod; res += ((a*c) % mod); res %= mod; a = minant % mod; int res2 = (c-1)*(a-1); res2 %= mod; res2 *= c; res2 %= mod; res2 *= a; res2 %= mod; res2 *= binpow(4, mod-2, mod); res2 %= mod; aux = (a+c-2)*a; aux %= mod; aux *= c; aux %= mod; aux *= binpow(2, mod-2, mod); aux %= mod; res2 += aux; res2 %= mod; res2 += ((a*c) % mod); res2 %= mod; // cout << res2 << "\n"; res = res-res2; res %= mod; res += mod; res %= mod; // cout << l << ' ' << r << ' ' << minant << ": " << res << "\n"; return res % mod; } int32_t main(){ cin >> n; for(int i = 1;i <= n;i++){ cin >> h[i]; } for(int i = 1;i <= n;i++){ cin >> w[i]; } seg.build(1, n, 1); queue <array <int,4>> q; q.push({1, n, 0, 0}); for(int i = 1;i <= n;i++){ pref[i] = pref[i-1] + w[i]; pref[i] %= mod; } int res = 0; while(!q.empty()){ auto [l, r, minant, aux] = q.front(); q.pop(); if(aux == 0){ res += query(l, r, minant); res %= mod; auto [minn, pos] = seg.query(l, r, 1, n, 1); if(pos != l) q.push({l, pos-1, minn, 0}); if(pos != r) q.push({pos+1, r, minn, 1}); } else{ auto [minn, pos] = seg.query(l, r, 1, n, 1); if(minant == minn){ if(pos != l) q.push({l, pos-1, minn, 0}); if(pos != r) q.push({pos+1, r, minn, 1}); } else{ q.push({l, r, minant, 0}); } } } // cout << binpow(4, mod-1, mod); cout << res << '\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...
#Verdict Execution timeMemoryGrader output
Fetching results...