数列分块入门 4
#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 = 998244353; 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, opt, l, r, c, block; LL a[maxn]; int bl[maxn]; LL sum[maxn]; LL change[maxn]; void add(int x, int y, int val) { for (int i = x; i <= min(block * bl[x], y); i++) {//直接暴力维护x块 a[i] += val; sum[bl[i]] += val; } if (bl[x] != bl[y]) {//如果不在同一块 for (int i = block * (bl[y] - 1) + 1; i <= min(block * bl[y], y); i++) {//那y块也暴力维护 a[i] += val; sum[bl[i]] += val; } for (int i = bl[x] + 1; i < bl[y]; i++) {//x和y块之间直接整块维护 change[i] += val; } } } void query(int x, int y, int k) { LL ans = 0; for (int i = x; i <= min(block * bl[x], y); i++) {//加上x块的 ans = (ans + a[i] + change[bl[i]]) % k; } if (bl[x] != bl[y]) {//不在同一块 for (int i = block * (bl[y] - 1) + 1; i <= min(block * bl[y], y); i++) {//加上y块的 ans = (ans + a[i] + change[bl[i]]) % k; } for (int i = bl[x] + 1; i < bl[y]; i++) {//加上x和y整块的和 ans = (ans + change[i] * block % k + sum[i] % k) % k; } } ans = ans % k; printf("%lld\n", ans); } int main() { io; n = read(); block = sqrt(n); for (int i = 1; i <= n; i++) { a[i] = read(); } for (int i = 1; i <= n; i++) { bl[i] = (i - 1) / block + 1; sum[bl[i]] += a[i]; } for (int i = 1; i <= n; i++) { opt = read(); l = read(); r = read(); c = read(); if (opt == 0) add(l, r, c); else query(l, r, c + 1); } return 0; }