Hướng dẫn giải của Bedao OI Contest 5 - One Shot
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
#include "bits/stdc++.h" using namespace std; #ifdef LOCAL #include "debug.h" #else #define debug(...) #endif using ll = long long; using pii = pair<int, int>; #define F first #define S second #define sz(x) (int)((x).size()) #define all(x) (x).begin(), (x).end() mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); ll get_rand(ll l, ll r) { assert(l <= r); return uniform_int_distribution<ll> (l, r)(rng); } const int N = 2e5 + 3; const ll mod = 1e9 + 7; ll qpow(ll a, ll b){ ll res = 1; for(; b > 0; b >>= 1, a = a * a % mod) if(b & 1) res = res * a % mod; return res; } int n, l[N], r[N]; ll a[N], range[N]; namespace Sub1{ bool valid_input(){ ll d = 1; for(int i = 1; i <= n; ++i){ d = d * range[i]; if(d > 1e6) return 0; } return 1; } ll tot = 0, cnt = 1, sum = 0; int bad[N]; void go(int id){ if(id == n + 1){ sum += (tot + mod * mod) % mod; if(sum >= mod) sum -= mod; return; } for(int i = l[id], t = range[id]; t > 0; --t, i = (i == n ? 1 : i + 1)){ ++bad[i]; if(bad[i] == 1) tot += 2 * a[i]; go(id + 1); if(bad[i] == 1) tot -= 2 * a[i]; --bad[i]; } } void solve(){ tot = -accumulate(a + 1, a + n + 1, 0ll); for(int i = 1; i <= n; ++i) cnt = cnt * range[i] % mod; go(1); cout << sum * qpow(cnt, mod - 2) % mod; } } namespace Sub2{ bool valid_input(){ return n <= 5000; } ll p[N]; bool inside(int x, int lv, int rv){ if(lv <= rv) return lv <= x and x <= rv; return (lv <= x and x <= n) or (x <= rv); } void solve(){ ll res = 0; for(int i = 1; i <= n; ++i){ p[i] = 1; for(int j = 1; j <= n; ++j){ if(inside(i, l[j], r[j])) p[i] = (p[i] * (range[j] - 1) % mod) * qpow(range[j], mod - 2) % mod; } res += (a[i] - (2 * a[i] * p[i] % mod) + mod) % mod; if(res >= mod) res -= mod; } cout << res; } } // segtree ll st[4 * N], lazy[4 * N]; void down(int id){ ll &x = lazy[id]; st[id << 1] = st[id << 1] * x % mod; st[id << 1 | 1] = st[id << 1 | 1] * x % mod; lazy[id << 1] = lazy[id << 1] * x % mod; lazy[id << 1 | 1] = lazy[id << 1 | 1] * x % mod; x = 1; } void update(int id, int l, int r, int tl, int tr, ll val){ if(l > tr or tl > r) return; if(tl <= l and r <= tr){ st[id] = st[id] * val % mod; lazy[id] = lazy[id] * val % mod; return; } int mid = (l + r) >> 1; down(id); update(id << 1, l, mid, tl, tr, val); update(id << 1 | 1, mid + 1, r, tl, tr, val); st[id] = st[id << 1] * st[id << 1 | 1] % mod; } ll get(int id, int l, int r, int pos){ if(l == r) return st[id]; int mid = (l + r) >> 1; down(id); if(pos <= mid) return get(id << 1, l, mid, pos); return get(id << 1 | 1, mid + 1, r, pos); } namespace Sub3{ void solve(){ for(int i = 0; i < 4 * N; ++i) st[i] = lazy[i] = 1; for(int i = 1; i <= n; ++i){ ll x = (range[i] - 1) * qpow(range[i], mod - 2) % mod; if(l[i] <= r[i]){ update(1, 1, n, l[i], r[i], x); } else{ update(1, 1, n, l[i], n, x); update(1, 1, n, 1, r[i], x); } } ll res = 0; for(int i = 1; i <= n; ++i){ ll p = get(1, 1, n, i); res += (a[i] - (2 * a[i] * p % mod) + mod) % mod; if(res >= mod) res -= mod; } cout << res; } } void solve(){ cin >> n; for(int i = 1; i <= n; ++i) cin >> a[i]; for(int i = 1; i <= n; ++i){ cin >> l[i] >> r[i]; if(l[i] <= r[i]) range[i] = r[i] - l[i] + 1; else range[i] = (n - l[i] + 1) + r[i]; } Sub3::solve(); } int32_t main() { cin.tie(nullptr)->sync_with_stdio(0); #define task "oneshot" if(fopen(task".inp", "r")){ freopen(task".inp", "r", stdin); freopen(task".out", "w", stdout); } int test = 1; // cin >> test; for(int i = 1; i <= test; ++i){ // cout << "Case #" << i << ": "; solve(); } #ifdef LOCAL cerr << "\n[Time]: " << 1000.0 * clock() / CLOCKS_PER_SEC << " ms.\n"; #endif return 0; }
Bình luận
hi