#include <cstdio> #include <vector> #include <algorithm> #include <map> using namespace std; const int Q = ((int)1e9) + 7; void dod(int &x, long long y) { x += y % Q; if (x >= Q) x -= Q; } struct drz { int get(long long r, long long aa = 2) { return (sum * aa + r * num) % Q; } void fill(vector<int>& v, int r) { for (int i = 0; i < g; i++) v.push_back(r+i+i); } int sum; int num; int g; }; drz mnd(const drz& d, long long a) { drz ret; ret.g = (a % 2 == 0 ? 1 : d.g + 1); ret.num = (a * d.num + 1) % Q; ret.sum = (a * (d.num + d.sum)) % Q; return ret; } int div2(int x) { x %= Q; if (x % 2) x+=Q; return x/2; } int main() { int n,q; scanf("%d %d",&n,&q); vector<int> a(n-1); for (int i = 0; i < n-1; i++) { scanf("%d",&a[i]); } vector<drz> d(n); d[n-1].sum = 0; d[n-1].num = 1; d[n-1].g = 1; for (int i = n-2; i >= 0; i--) { d[i] = mnd(d[i+1], a[i]); } for (int ii = 0; ii < q; ii++) { int A,B,C,odwr=0; scanf("%d %d %d",&A,&B,&C); A--,B--,C--; if (B > A) swap(A, B), odwr=1; int odl = A-C + B-C; int oA = 0; int ret = d[A].get(odl); int sumA = d[A].get(oA, 1); vector<int> s; d[A].fill(s, odl); while (A > B) { A--; oA++; drz x = mnd(d[A+1], a[A]-1); dod(ret, x.get(odl)); dod(sumA, x.get(oA, 1)); x.fill(s, odl); } if (B > C) { dod(ret, d[B].get(odl)); dod(sumA, d[B].get(odl, 1)); d[B].fill(s, odl); } int oAB = odl; while (A > C) { A--, B--; oA++; oAB--; if (A > C) { // jednakowe drz x = mnd(d[A+1], a[A]-1); dod(ret, x.get(odl) * 2); dod(sumA, x.get(oA, 1) + x.get(oAB, 1)); } else { // w C drz x = mnd(d[A+1], a[A]-2); dod(ret, x.get(odl)); dod(sumA, x.get(oA, 1)); x.fill(s, odl); } } while(C > 0) { C--; odl += 2; oA++; drz x = mnd(d[C+1], a[C]-1); dod(ret, x.get(odl)); dod(sumA, x.get(oA, 1)); x.fill(s, odl); } long long ss = 0, ssB = 0; sort(s.begin(), s.end()); for (int i = 0; i < s.size(); i++) ss += s[i]; for (int i = s.size()-2; i >= 0; i-=2) ssB += s[i]; if (odwr) sumA = (ret-sumA+Q)%Q; // printf("sumA = %d\nret = %d\nss = %lld\n,ssB = %lld\n",sumA,ret,ss,ssB); // printf("{"); for (int i = 0; i < s.size(); i++) printf(" %d", s[i]); printf("}\n"); int xx = ((sumA - div2(ret - ss%Q + Q) - ssB % Q) % Q + Q) % Q; printf("%d\n", xx); } 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 107 108 109 110 111 112 113 114 115 116 117 118 | #include <cstdio> #include <vector> #include <algorithm> #include <map> using namespace std; const int Q = ((int)1e9) + 7; void dod(int &x, long long y) { x += y % Q; if (x >= Q) x -= Q; } struct drz { int get(long long r, long long aa = 2) { return (sum * aa + r * num) % Q; } void fill(vector<int>& v, int r) { for (int i = 0; i < g; i++) v.push_back(r+i+i); } int sum; int num; int g; }; drz mnd(const drz& d, long long a) { drz ret; ret.g = (a % 2 == 0 ? 1 : d.g + 1); ret.num = (a * d.num + 1) % Q; ret.sum = (a * (d.num + d.sum)) % Q; return ret; } int div2(int x) { x %= Q; if (x % 2) x+=Q; return x/2; } int main() { int n,q; scanf("%d %d",&n,&q); vector<int> a(n-1); for (int i = 0; i < n-1; i++) { scanf("%d",&a[i]); } vector<drz> d(n); d[n-1].sum = 0; d[n-1].num = 1; d[n-1].g = 1; for (int i = n-2; i >= 0; i--) { d[i] = mnd(d[i+1], a[i]); } for (int ii = 0; ii < q; ii++) { int A,B,C,odwr=0; scanf("%d %d %d",&A,&B,&C); A--,B--,C--; if (B > A) swap(A, B), odwr=1; int odl = A-C + B-C; int oA = 0; int ret = d[A].get(odl); int sumA = d[A].get(oA, 1); vector<int> s; d[A].fill(s, odl); while (A > B) { A--; oA++; drz x = mnd(d[A+1], a[A]-1); dod(ret, x.get(odl)); dod(sumA, x.get(oA, 1)); x.fill(s, odl); } if (B > C) { dod(ret, d[B].get(odl)); dod(sumA, d[B].get(odl, 1)); d[B].fill(s, odl); } int oAB = odl; while (A > C) { A--, B--; oA++; oAB--; if (A > C) { // jednakowe drz x = mnd(d[A+1], a[A]-1); dod(ret, x.get(odl) * 2); dod(sumA, x.get(oA, 1) + x.get(oAB, 1)); } else { // w C drz x = mnd(d[A+1], a[A]-2); dod(ret, x.get(odl)); dod(sumA, x.get(oA, 1)); x.fill(s, odl); } } while(C > 0) { C--; odl += 2; oA++; drz x = mnd(d[C+1], a[C]-1); dod(ret, x.get(odl)); dod(sumA, x.get(oA, 1)); x.fill(s, odl); } long long ss = 0, ssB = 0; sort(s.begin(), s.end()); for (int i = 0; i < s.size(); i++) ss += s[i]; for (int i = s.size()-2; i >= 0; i-=2) ssB += s[i]; if (odwr) sumA = (ret-sumA+Q)%Q; // printf("sumA = %d\nret = %d\nss = %lld\n,ssB = %lld\n",sumA,ret,ss,ssB); // printf("{"); for (int i = 0; i < s.size(); i++) printf(" %d", s[i]); printf("}\n"); int xx = ((sumA - div2(ret - ss%Q + Q) - ssB % Q) % Q + Q) % Q; printf("%d\n", xx); } return 0; } |