Halal Questions
It may be considered to enumerate each element to count the coefficient of its occurrence * its weight.
The number of occurrences of \ (a [x] \) and \ (a [n-x + 1] \) is the same, so only half of the whole sequence is left.
First consider how many times \ (a [x] (x \ le (n + 1) / 2) \) will appear in length \ (y \) .
After discussion, it was found to be \ (min (x, y, n-y + 1) \)
Then suppose \ (y \ le (n + 1) / 2 \) , the greater part is the same.
The last thing is to ask for such a thing \ ((r <= (n + 1) / 2) \) :
\ (\ sum_ {i = 1} ^ {(n + 1) / 2} a [i] * \ sum_ { j = 1} ^ {r} min (i, j) \)
Disassemble the formula and find that maintaining the interval sum of \ (a [i] * i ^ {0..2} \) is just fine.
Code:
#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
#define ff(i, x, y) for(int i = x, _b = y; i < _b; i ++)
#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;
const int mo = 1e9 + 7;
ll ksm(ll x, ll y) {
ll s = 1;
for(; y; y /= 2, x = x * x % mo)
if(y & 1) s = s * x % mo;
return s;
}
const ll ni2 = ksm(2, mo - 2);
const int N = 2e5 + 5;
int n, m, n0, op, x, y, z;
#define i0 i + i
#define i1 i + i + 1
ll g[N * 4][3], t[N * 4][3], lz[N * 4];
void bt(int i, int x, int y) {
if(x == y) {
g[i][0] = 1;
g[i][1] = x;
g[i][2] = (ll) x * x % mo;
return;
}
int m = x + y >> 1;
bt(i0, x, m); bt(i1, m + 1, y);
fo(j, 0, 2) g[i][j] = (g[i0][j] + g[i1][j]) % mo;
}
int pl, pr, px;
void jia(int i, int px) {
fo(j, 0, 2) t[i][j] = (t[i][j] + g[i][j] * px) % mo;
lz[i] = (lz[i] + px) % mo;
}
void down(int i) {
if(lz[i]) jia(i0, lz[i]), jia(i1, lz[i]), lz[i] = 0;
}
void add(int i, int x, int y) {
if(y < pl || x > pr) return;
if(x >= pl && y <= pr) {
jia(i, px);
return;
}
int m = x + y >> 1; down(i);
add(i0, x, m); add(i1, m + 1, y);
fo(j, 0, 2) t[i][j] = (t[i0][j] + t[i1][j]) % mo;
}
ll py[3];
void ft(int i, int x, int y) {
if(y < pl || x > pr) return;
if(x >= pl && y <= pr) {
fo(j, 0, 2) py[j] = (py[j] + t[i][j]) % mo;
return;
}
int m = x + y >> 1; down(i);
ft(i0, x, m); ft(i1, m + 1, y);
}
void xiu(int x, int y, int z) {
if(x <= n0) {
pl = x, pr = min(y, n0), px = z;
add(1, 1, n0);
}
if(y > n0) {
pl = n - y + 1, pr = n - max(x, n0 + 1) + 1; px = z;
add(1, 1, n0);
}
}
ll calc(int r) {
ll ans = 0;
pl = 1, pr = r; fo(j, 0, 2) py[j] = 0;
ft(1, 1, n0);
ans = (ans + (py[2] + py[1]) * ni2 % mo - py[2] + py[1] * r + mo) % mo;
pl = r + 1, pr = n0; fo(j, 0, 2) py[j] = 0;
ft(1, 1, n0);
ans = (ans + py[0] * ((ll) r * (r + 1) / 2 % mo)) % mo;
return ans;
}
ll qry(int r) {
if(r <= n0) return calc(r);
return (calc(n0) + (n % 2 == 1 ? calc(n0 - 1) : calc(n0)) - calc(n - r) + mo) % mo;
}
int main() {
scanf("%d %d", &n, &m);
n0 = (n + 1) / 2;
bt(1, 1, n0);
fo(i, 1, n) {
scanf("%d", &x);
xiu(i, i, x);
}
fo(ii, 1, m) {
scanf("%d %d %d", &op, &x, &y);
if(op == 1) {
scanf("%d", &z);
if(x > y) swap(x, y);
xiu(x, y, z);
} else {
ll s = (qry(y) - qry(x - 1) + mo) % mo;
pp("%lld\n", s);
}
}
}