rt, 这几天一直在写这题, 一共写了五棵, 这颗是表现最好的, 能过掉样例(subtask0) 和后面零星几个数据点, 其他数据点全部 WA
#include <bits/stdc++.h>
using std::cin;
using std::cout;
using std::vector;
typedef long long ll;
typedef vector<ll> V;
typedef vector<ll>::iterator iter;
const ll MOD = 1e9 + 7;
const ll MAX = 1e5 + 5;
ll n, m, l, r, op, x;
ll num[MAX], opr[MAX];
ll qp(ll a, ll x)
{
ll res = 1;
while (x)
{
if (x & 1) { res = res * a % MOD; }
a = a * a % MOD; x >>= 1;
}
return res % MOD;
}
struct T
{
bool at, mt, op;
int lv, rv;
int * c; V v;
ll ln, sq;
ll sm, ml, lm, rm, lc, rc, vl, ag;
void clear()
{
for (int i = 1; i <= sq; ++i) { c[i] = 0; } v.clear();
}
void asgadd()
{
vl = sm % MOD; op = 0; lc = rc = 1; lm = lv, rm = rv;
clear(); c[1] += ln;
at = true; mt = false;
}
void asgmul()
{
vl = ml % MOD; op = 1; lc = rc = ln; lm = rm = ml % MOD;
clear(); if (ln <= sq) { ++c[ln]; } else { v.push_back(ln); }
mt = true; at = false;
}
void asg(ll v)
{
v %= MOD; lv = rv = v; vl = 0;
lm = qp(v, lc); rm = qp(v, rc); ml = qp(v, ln); sm = v * ln % MOD;
ll now = v;
for (int i = 1; i <= sq; ++i, now = now * v % MOD)
{
if (c[i])
{
vl = (vl + 1ll * now * c[i] % MOD) % MOD;
}
}
for (int i : this -> v)
{
vl = (vl + qp(v, i)) % MOD;
}
ag = v;
}
void merge(T & l, T & r)
{
sm = (l.sm + r.sm) % MOD;
ml = 1ll * l.ml * r.ml % MOD;
lv = l.lv, rv = r.rv;
op = r.op;
lm = l.lm % MOD, rm = r.rm % MOD, lc = l.lc, rc = r.rc;
if (l.op and l.lc == l.ln) { lc = l.ln + r.lc; lm = 1ll * l.ml * r.lm % MOD; }
if (l.op and r.rc == r.ln) { rc = r.ln + l.rc; rm = 1ll * r.ml * l.rm % MOD; }
vl = (l.vl + r.vl) % MOD;
if (l.op)
{
vl = ((((l.vl + r.vl) % MOD + 1ll * l.rm * r.lm % MOD) % MOD - (l.rm + r.lm) % MOD) % MOD + MOD) % MOD;
}
clear();
for (int i = 1; i <= l.sq; ++i) { c[i] += l.c[i]; }
for (int i = 1; i <= r.sq; ++i) { c[i] += r.c[i]; }
int i1 = 0, i2 = 0, e1 = l.v.size(), e2 = r.v.size();
while (i1 < e1 and i2 < e2)
{
if (l.v[i1] < r.v[i2])
{
if (l.v[i1] <= sq) { c[l.v[i1]]++; }
else { v.push_back(l.v[i1]); }
++i1;
}
else
{
if (r.v[i2] <= sq) { c[r.v[i2]]++; }
else { v.push_back(r.v[i2]); }
++i2;
}
}
while (i1 < e1)
{
if (l.v[i1] <= sq) { c[l.v[i1]]++; }
else { v.push_back(l.v[i1]); }
++i1;
}
while (i2 < e2)
{
if (r.v[i2] <= sq) { c[r.v[i2]]++; }
else { v.push_back(r.v[i2]); }
++i2;
}
if (l.op)
{
if (l.rc <= sq) { --c[l.rc]; }
else { iter i = lower_bound(v.begin(), v.end(), l.rc); v.erase(i); }
if (r.lc <= sq) { --c[r.lc]; }
else { iter i = lower_bound(v.begin(), v.end(), r.lc); v.erase(i); }
if (l.rc + r.lc <= sq) { ++c[l.rc + r.lc]; }
else { iter i = lower_bound(v.begin(), v.end(), l.rc + r.lc); v.insert(i, l.rc + r.lc); }
}
}
void pushdown(T & l, T & r)
{
if (ag) { l.asg(ag); r.asg(ag); ag = 0; }
if (at) { l.asgadd(); r.asgadd(); at = false; }
if (mt) { l.asgmul(); r.asgmul(); mt = false; }
}
} a[MAX << 2 | 1];
struct A
{
ll lm, rm, lc, rc, vl, ln, op;
};
A merge(A l, A r)
{
A x;
x.op = r.op; x.ln = l.ln + r.ln;
x.lc = l.lc; x.rc = r.rc;
x.lm = l.lm; x.rm = r.rm;
if (l.op and l.lc == l.ln) { x.lc = l.ln + r.lc; x.lm = 1ll * l.lm * r.lm; }
if (l.op and r.rc == r.ln) { x.rc = r.ln + l.rc; x.rm = 1ll * r.rm * l.rm; }
x.vl = (l.vl + r.vl) % MOD;
if (l.op)
{
x.vl = (((x.vl + 1ll * l.rm * r.lm) % MOD - (l.rm + r.lm) % MOD) % MOD + MOD) % MOD;
}
return x;
}
A query(int l, int r, int s, int t, int x)
{
if (l >= s and r <= t) { return {a[x].lm, a[x].rm, a[x].lc, a[x].rc, a[x].vl % MOD, a[x].ln, a[x].op}; }
a[x].pushdown(a[x << 1], a[x << 1 | 1]);
int k = l + ((r - l) >> 1);
if (k >= t) { return query(l, k, s, t, x << 1); }
else if (k < s) { return query(k + 1, r, s, t, x << 1 | 1); }
else { return merge(query(l, k, s, t, x << 1), query(k + 1, r, s, t, x << 1 | 1)); }
}
void build(int l, int r, int x)
{
a[x].ln = r - l + 1; a[x].sq = sqrt(a[x].ln); a[x].c = new int [a[x].sq + 3]();
if (l == r)
{
a[x].vl = a[x].lv = a[x].rv = a[x].lm = a[x].rm = a[x].sm = a[x].ml = num[l];
a[x].op = opr[l]; a[x].lc = a[x].rc = 1; a[x].c[1] = 1;
return ;
}
int k = l + ((r - l) >> 1);
build(l, k, x << 1); build(k + 1, r, x << 1 | 1);
a[x].merge(a[x << 1], a[x << 1 | 1]);
}
void asg(int l, int r, int s, int t, ll v, int x)
{
if (l >= s and r <= t) { a[x].asg(v); return ; }
a[x].pushdown(a[x << 1], a[x << 1 | 1]);
int k = l + ((r - l) >> 1);
if (k >= s) { asg(l, k, s, t, v, x << 1); }
if (k < t) { asg(k + 1, r, s, t, v, x << 1 | 1); }
a[x].merge(a[x << 1], a[x << 1 | 1]);
}
void asgadd(int l, int r, int s, int t, int x)
{
if (l >= s and r <= t) { a[x].asgadd(); return ; }
a[x].pushdown(a[x << 1], a[x << 1 | 1]);
int k = l + ((r - l) >> 1);
if (k >= s) { asgadd(l, k, s, t, x << 1); }
if (k < t) { asgadd(k + 1, r, s, t, x << 1 | 1); }
a[x].merge(a[x << 1], a[x << 1 | 1]);
}
void asgmul(int l, int r, int s, int t, int x)
{
if (l >= s and r <= t) { a[x].asgmul(); return ; }
a[x].pushdown(a[x << 1], a[x << 1 | 1]);
int k = l + ((r - l) >> 1);
if (k >= s) { asgmul(l, k, s, t, x << 1); }
if (k < t) { asgmul(k + 1, r, s, t, x << 1 | 1); }
a[x].merge(a[x << 1], a[x << 1 | 1]);
}
int main()
{
// cin.tie(NULL); cout.tie(NULL); std::ios::sync_with_stdio(false);
cin >> n >> m;
for (int i = 1; i <= n; ++i) { cin >> num[i]; num[i] %= MOD; }
for (int i = 1; i < n; ++i) { cin >> opr[i]; }
build(1, n, 1);
while (m--)
{
cin >> op >> l >> r;
if (op != 3) { cin >> x; }
if (op == 1) { asg(1, n, l, r, x % MOD, 1); }
else if (op == 2)
{
if (x == 0) { asgadd(1, n, l, r, 1); }
else { asgmul(1, n, l, r, 1); }
}
else { cout << query(1, n, l, r, 1).vl % MOD << '\n'; }
}
}