数列分块入门 7
思路:先分块,对于更新操作,如果是左右两边的块,由于不一定是对块的全部数操作,所以要先对直接已经预先乘和加的更新,否则如果是中间块,直接更新块即可
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstring> #include <stdio.h> #include <algorithm> #include <map> #include <queue> #include <set> #include <sstream> #include <vector> #include <cmath> #include <stack> #include <random> using namespace std; #define io ios::sync_with_stdio(0),cin.tie(0) #define ms(arr) memset(arr,0,sizeof(arr)) #define LD long double #define LL long long #define PI acos(-1.0) #define INF 0x3f3f3f3f #define inf 1<<30 #define ull unsigned long long const int Mod = 10007; const int maxn = 1e6 + 5; int read() { int x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } int n, m, block; int opt, l, r, c; int a[maxn]; int belong[maxn]; int add[maxn]; int mul[maxn]; void rest(int x) {//对当前块依次更新 for (int i = (belong[x] - 1) * block + 1; i <= min(belong[x] * block, n); i++) { a[i] = (mul[belong[i]] * a[i] + add[belong[i]]) % Mod; } mul[belong[x]] = 1; add[belong[x]] = 0; } void Add(int l, int r, int val) { rest(l);//先对l块更新再操作 for (int i = l; i <= min(r, belong[l] * block); i++) { a[i] = (a[i]+val) % Mod; } if (belong[l] != belong[r]) {//不在同一块 rest(r);//对r块进行更新 for (int i = (belong[r] - 1) * block + 1; i <= min(r, belong[r] * block); i++) {//对最右边块操作 a[i] = (a[i] + val) % Mod; } for (int i = belong[l] + 1; i <= belong[r] - 1; i++) {//中间块不必更新,直接操作即可 add[i] = (add[i] + val) % Mod; } } } void Mul(int l, int r, int val) { rest(l);//先更新 for (int i = l; i <= min(r, belong[l] * block); i++) {//对最左边块更新 a[i] = (a[i] * val) % Mod; } if (belong[l] != belong[r]) {//不在同一块 rest(r);//更新最右边块 for (int i = (belong[r] - 1) * block + 1; i <= min(r, belong[r] * block); i++) {//操作 a[i] = (a[i] * val) % Mod; } for (int i = belong[l] + 1; i <= belong[r] - 1; i++) {//对中间块操作 add[i] = (add[i] * val) % Mod;//对中间块预先加的也要乘 mul[i] = (mul[i] * val) % Mod; } } } int query(int x) { int ans; ans = (a[x] * mul[belong[x]] + add[belong[x]]) % Mod;//询问时候返回 return ans; } int main() { scanf("%d", &n); block = sqrt(n); m = n / block; if (n % block) m++; for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); a[i] %= Mod; belong[i] = (i - 1) / block + 1; add[belong[i]] = 0; mul[belong[i]] = 1; } for (int i = 1; i <= n; i++) { scanf("%d%d%d%d", &opt, &l, &r, &c); if (opt == 0) { Add(l, r, c); } else if (opt == 1) { Mul(l, r, c); } else { cout << query(r) << endl; } } }