#pragma GCC optimize ("O3") #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> ii; typedef vector<int> vi; const int INF = 0x3f3f3f3f; #define FOR(i,b,e) for(int i = (b); i < (e); i++) #define TRAV(x,a) for(auto &x: (a)) #define SZ(x) ((int)x.size()) #define PB push_back #define X first #define Y second const int N = 3e5+5; const int mod = 1e9+7; const int inv2 = (mod+1)/2; int sumOdl[N], syny[N], subtree[N], layer[N], dist[N], npPath[N]; int n; bool ziom[N]; int query(int v, int u, int lca){ int maks = 0; int minCost = v + u - 2*lca; int distSum = (dist[v] - dist[u] + mod) % mod; int ile = 0; FOR(j, 0, 2){ swap(v, u); if(v == lca){ ile++; continue; } FOR(i, 0, npPath[v]) ziom[i] ^= 1; maks = max(maks, npPath[v]); v--; while(v != lca){ if((syny[v]&1) == 0){ FOR(i, 1, npPath[v+1]+1) ziom[i] ^= 1; maks = max(maks, npPath[v+1]+1); } ziom[0] ^= 1; v--; } } int akt = 0; if(ile == 1) akt--, v++; else{ FOR(i, 0, npPath[v]) ziom[i] ^= 1; maks = max(maks, npPath[v]); } v--; while(v > 0){ akt++; ziom[akt] ^= 1; maks = max(maks, akt); if((syny[v]&1) == 0){ FOR(i, 1, npPath[v+1]+1) ziom[i+akt] ^= 1; maks = max(maks, npPath[v+1]+1+akt); } v--; } int sign = 1, sum = 0; for(int i = maks; i >= 0; i--){ if(ziom[i]){ sum = (sum + sign*2*i + mod) % mod; sign *= -1; } } if(sign == -1) sum = (sum + minCost) % mod; memset(ziom, 0, maks+1); return 1ll*(sum + distSum) * inv2 % mod; } void solve(){ int q; cin >> n >> q; FOR(i, 1, n) cin >> syny[i]; subtree[n] = 1; for(int i = n-1; i > 0; i--) subtree[i] = (1ll*subtree[i+1]*syny[i] + 1) % mod; layer[1] = 1; FOR(i, 2, n+1) layer[i] = 1ll*layer[i-1]*syny[i-1] % mod; FOR(i, 1, n+1) dist[1] = (dist[1] + 1ll*(i-1)*layer[i]) % mod; FOR(i, 2, n+1) dist[i] = (dist[i-1] + subtree[1] - 2ll*subtree[i] + 2*mod) % mod; for(int i = n; i > 0; i--){ if(syny[i]&1) npPath[i] = npPath[i+1]; npPath[i]++; } FOR(i, 0, q){ int a, b, c; cin >> a >> b >> c; cout << query(a, b, c) << '\n'; } } int main(){ ios::sync_with_stdio(0); cin.tie(0); // int tt; cin >> tt; // FOR(te, 0, tt) solve(); return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | #pragma GCC optimize ("O3") #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> ii; typedef vector<int> vi; const int INF = 0x3f3f3f3f; #define FOR(i,b,e) for(int i = (b); i < (e); i++) #define TRAV(x,a) for(auto &x: (a)) #define SZ(x) ((int)x.size()) #define PB push_back #define X first #define Y second const int N = 3e5+5; const int mod = 1e9+7; const int inv2 = (mod+1)/2; int sumOdl[N], syny[N], subtree[N], layer[N], dist[N], npPath[N]; int n; bool ziom[N]; int query(int v, int u, int lca){ int maks = 0; int minCost = v + u - 2*lca; int distSum = (dist[v] - dist[u] + mod) % mod; int ile = 0; FOR(j, 0, 2){ swap(v, u); if(v == lca){ ile++; continue; } FOR(i, 0, npPath[v]) ziom[i] ^= 1; maks = max(maks, npPath[v]); v--; while(v != lca){ if((syny[v]&1) == 0){ FOR(i, 1, npPath[v+1]+1) ziom[i] ^= 1; maks = max(maks, npPath[v+1]+1); } ziom[0] ^= 1; v--; } } int akt = 0; if(ile == 1) akt--, v++; else{ FOR(i, 0, npPath[v]) ziom[i] ^= 1; maks = max(maks, npPath[v]); } v--; while(v > 0){ akt++; ziom[akt] ^= 1; maks = max(maks, akt); if((syny[v]&1) == 0){ FOR(i, 1, npPath[v+1]+1) ziom[i+akt] ^= 1; maks = max(maks, npPath[v+1]+1+akt); } v--; } int sign = 1, sum = 0; for(int i = maks; i >= 0; i--){ if(ziom[i]){ sum = (sum + sign*2*i + mod) % mod; sign *= -1; } } if(sign == -1) sum = (sum + minCost) % mod; memset(ziom, 0, maks+1); return 1ll*(sum + distSum) * inv2 % mod; } void solve(){ int q; cin >> n >> q; FOR(i, 1, n) cin >> syny[i]; subtree[n] = 1; for(int i = n-1; i > 0; i--) subtree[i] = (1ll*subtree[i+1]*syny[i] + 1) % mod; layer[1] = 1; FOR(i, 2, n+1) layer[i] = 1ll*layer[i-1]*syny[i-1] % mod; FOR(i, 1, n+1) dist[1] = (dist[1] + 1ll*(i-1)*layer[i]) % mod; FOR(i, 2, n+1) dist[i] = (dist[i-1] + subtree[1] - 2ll*subtree[i] + 2*mod) % mod; for(int i = n; i > 0; i--){ if(syny[i]&1) npPath[i] = npPath[i+1]; npPath[i]++; } FOR(i, 0, q){ int a, b, c; cin >> a >> b >> c; cout << query(a, b, c) << '\n'; } } int main(){ ios::sync_with_stdio(0); cin.tie(0); // int tt; cin >> tt; // FOR(te, 0, tt) solve(); return 0; } |