思路:三种改变的顺序,先变 后乘 再 加。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <sstream>
using namespace std;
typedef long long LL;
const int N = 5e5 + 4, mod = 1e4 + 7;
int n, m;struct seg
{int sum[4], lazy[4];
}tr[N<<4];#define ls (u<<1)
#define rs (u<<1|1)
#define mid (l+r>>1)
// 忽然发现这样写好简单;
void push_up(int u){for(int i = 1;i <= 3;i ++)tr[u].sum[i] = (tr[ls].sum[i] + tr[rs].sum[i])%mod;} void add_tage(int u, int a, int b, int c, int l, int r)
{if(a) // 先 变成 a {tr[u].lazy[1] = a, tr[u].lazy[2] = tr[u].lazy[3] = 0; tr[u].sum[1] = (LL)(r-l+1)*a%mod;tr[u].sum[2] = (LL)(r-l+1)*a*a%mod;tr[u].sum[3] = (LL)(r-l+1)*a*a%mod*a%mod;}if(b) // 再 乘以 b {tr[u].lazy[2] = tr[u].lazy[2] ? tr[u].lazy[2]*b%mod : b;tr[u].lazy[3] = tr[u].lazy[3]*b%mod;tr[u].sum[1] = (LL)tr[u].sum[1]*b%mod;tr[u].sum[2] = (LL)tr[u].sum[2]*b*b%mod;tr[u].sum[3] = (LL)tr[u].sum[3]*b*b*b%mod;}if(c) // 再 加上 c {tr[u].lazy[3] = (tr[u].lazy[3] + c)%mod;tr[u].sum[3] = (tr[u].sum[3] + (LL)3*tr[u].sum[2]*c + (LL)3*tr[u].sum[1]*c*c + (LL)(r-l+1)*c*c*c)%mod;tr[u].sum[2] = (tr[u].sum[2] + 2*tr[u].sum[1]*c + (LL)(r-l+1)*c*c)%mod;tr[u].sum[1] = (tr[u].sum[1] + (r-l+1)*c)%mod;}
}void push_down(int u, int l, int r)
{add_tage(ls, tr[u].lazy[1], tr[u].lazy[2], tr[u].lazy[3], l, mid);add_tage(rs, tr[u].lazy[1], tr[u].lazy[2], tr[u].lazy[3], mid+1, r);tr[u].lazy[1] = tr[u].lazy[2] = tr[u].lazy[3] = 0;
}void update(int u, int l, int r, int L, int R, int a, int b, int c)
{if(L<=l&&R>=r) add_tage(u, a, b, c, l, r);else{push_down(u, l, r);if(L <= mid) update(ls, l, mid, L, R, a, b, c);if(R > mid) update(rs, mid+1, r, L, R, a, b, c);push_up(u);}return ;
}int quary(int u, int l, int r, int L, int R, int q)
{if(L<=l&&R>=r) return tr[u].sum[q]; push_down(u ,l ,r);int sum = 0;if(L <= mid) sum = quary(ls, l ,mid, L, R, q);if(R > mid) sum += quary(rs, mid+1, r, L, R, q);return sum%mod;
}int main()
{int n, m;while(~scanf("%d%d", &n, &m),n||m){for(int i = 1;i <= n<<2;i ++)for(int j = 1;j <= 3;j ++)tr[i].sum[j] = tr[i].lazy[j] = 0;while(m --){int f, x, y, c[4] = {0, 0, 0, 0};scanf("%d%d%d", &f, &x, &y);scanf("%d", c+4-f);if(f != 4) update(1, 1, n, x, y, c[1], c[2], c[3]);else printf("%d\n", quary(1, 1, n, x, y, c[0]));}}return 0;
}