Please, another Queries on Array?
利用欧拉函数的计算方法, 用线段树搞一搞就好啦。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ull unsigned long long using namespace std; const int N = 4e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; const double PI = acos(-1); int n, q, tot, b[N], prime[301], mul[301]; LL S[301]; char op[20]; bool ok(int x) { for(int i = 2; i * i <= x; i++) if(x % i == 0) return false; return true; } int Power(int a, int b) { int ans = 1; while(b) { if(b & 1) ans = 1ll * ans * a % mod; a = 1ll * a * a % mod; b >>= 1; } return ans; } int a[N << 2], lazy[N << 2]; LL mask[N << 2], mlazy[N << 2]; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 inline void pull(int rt) { a[rt] = 1ll * a[rt << 1] * a[rt << 1 | 1] % mod; mask[rt] = mask[rt << 1] | mask[rt << 1 | 1]; } void push(int rt, int l, int mid, int r) { if(lazy[rt] != 1) { a[rt << 1] = 1ll * a[rt << 1] * Power(lazy[rt], mid - l + 1) % mod; a[rt << 1 | 1] = 1ll * a[rt << 1 | 1] * Power(lazy[rt], r - mid) % mod; lazy[rt << 1] = 1ll * lazy[rt << 1] * lazy[rt] % mod; lazy[rt << 1 | 1] = 1ll * lazy[rt << 1 | 1] * lazy[rt] % mod; lazy[rt] = 1; } if(mlazy[rt] != 0) { mask[rt << 1] |= mlazy[rt]; mask[rt << 1 | 1] |= mlazy[rt]; mlazy[rt << 1] |= mlazy[rt]; mlazy[rt << 1 | 1] |= mlazy[rt]; mlazy[rt] = 0; } } void build(int l, int r, int rt) { lazy[rt] = 1; mlazy[rt] = 0; if(l == r) { a[rt] = b[l]; mask[rt] = S[b[l]]; return; } int mid = l + r >> 1; build(lson); build(rson); pull(rt); } void update(int L, int R, int mul, int l, int r, int rt) { if(l >= L && r <= R) { a[rt] = 1ll * a[rt] * Power(mul, r - l + 1) % mod; lazy[rt] = 1ll * lazy[rt] * mul % mod; mask[rt] |= S[mul]; mlazy[rt] |= S[mul]; return; } int mid = l + r >> 1; push(rt, l, mid, r); if(L <= mid) update(L, R, mul, lson); if(R > mid) update(L, R, mul, rson); pull(rt); } PLI query(int L, int R, int l, int r, int rt) { if(l >= L && r <= R) return mk(mask[rt], a[rt]); int mid = l + r >> 1; push(rt, l, mid, r); PLI ans = mk(0, 1); if(L <= mid) { PLI tmp = query(L, R, lson); ans.fi |= tmp.fi; ans.se = 1ll * ans.se * tmp.se % mod; } if(R > mid) { PLI tmp = query(L, R, rson); ans.fi |= tmp.fi; ans.se = 1ll * ans.se * tmp.se % mod; } return ans; } int main() { for(int i = 2; i <= 300; i++) if(ok(i)) prime[tot++] = i; for(int i = 0; i < tot; i++) mul[i] = (1 - Power(prime[i], mod - 2) + mod) % mod; for(int i = 2; i <= 300; i++) for(int j = 0; j < tot && prime[j] <= i; j++) if(i % prime[j] == 0) S[i] |= 1ll << j; scanf("%d%d", &n, &q); for(int i = 1; i <= n; i++) scanf("%d", &b[i]); build(1, n, 1); while(q--) { scanf("%s", op); if(op[0] == 'T') { int L, R; scanf("%d%d", &L, &R); PLI ret = query(L, R, 1, n, 1); int ans = ret.se; LL mask = ret.fi; for(int i = 0; i < tot; i++) if(mask >> i & 1) ans = 1ll * ans * mul[i] % mod; printf("%d ", ans); } else { int L, R, x; scanf("%d%d%d", &L, &R, &x); update(L, R, x, 1, n, 1); } } return 0; } /* */