mx刚学分块,能过3个点,不知道是哪里写挂了还是维护的正确性有问题,有没有哪位dl能帮忙看看QAQ
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int MAXN = 100010;
const int SQRTN = 330;
const int MOD = 571373;
class Partitioning{
int len, partlen;
int sec[MAXN];
ll sum[MAXN], secsum[SQRTN], atag[SQRTN], mtag[SQRTN];
inline int left(int s){ return (s - 1) * partlen + 1; }
inline int right(int s){ return min(s * partlen, len); }
public:
inline void setup(int n){
len = n, partlen = sqrt(n);
for (int i = 1; i <= len; ++i){
scanf("%lld", &sum[i]), sum[i] %= MOD;
sec[i] = (i - 1) / partlen + 1;
mtag[sec[i]] = 1, atag[sec[i]] = 0;
(secsum[sec[i]] += sum[i]) %= MOD;
}
return;
}
inline void add(int l, int r, ll k){
if (sec[l] == sec[r]){
for (int i = l; i <= r; ++i){
(secsum[sec[i]] += k) %= MOD;
(sum[i] += k) %= MOD;
}
return;
}
int e = right(sec[l]);
for (int i = l; i <= e; ++i){
(secsum[sec[i]] += k) %= MOD;
(sum[i] += k) %= MOD;
}
for (int i = left(sec[r]); i <= r; ++i){
(secsum[sec[i]] += k) %= MOD;
(sum[i] += k) %= MOD;
}
for (int i = sec[l] + 1; i < sec[r]; ++i){
(secsum[i] += k * (right(i) - left(i) + 1)) %= MOD;
(atag[i] += k) %= MOD;
}
return;
}
inline void mul(int l, int r, ll k){
if (sec[l] == sec[r]){
for (int i = l; i <= r; ++i){
(secsum[sec[i]] += (k - 1) * sum[i]) %= MOD;
(sum[i] *= k) %= MOD;
}
return;
}
int e = right(sec[l]);
for (int i = l; i <= e; ++i){
(secsum[sec[i]] += (k - 1) * sum[i]) %= MOD;
(sum[i] *= k) %= MOD;
}
for (int i = left(sec[r]); i <= r; ++i){
(secsum[sec[i]] += (k - 1) * sum[i]) %= MOD;
(sum[i] *= k) %= MOD;
}
for (int i = sec[l] + 1; i < sec[r]; ++i){
(secsum[i] *= k) %= MOD;
(atag[i] *= k) %= MOD;
(mtag[i] *= k) %= MOD;
}
return;
}
inline ll query(int l, int r){
ll res = 0;
if (sec[l] == sec[r]){
for (int i = l; i <= r; ++i) (res += sum[i] * mtag[sec[i]] % MOD + atag[sec[i]]) %= MOD;
return res;
}
int e = right(sec[l]);
for (int i = l; i <= e; ++i) (res += sum[i] * mtag[sec[i]] % MOD + atag[sec[i]]) %= MOD;
for (int i = left(sec[r]); i <= r; ++i) (res += sum[i] * mtag[sec[i]] % MOD + atag[sec[i]]) %= MOD;
for (int i = sec[l] + 1; i < sec[r]; ++i) (res += secsum[i]) %= MOD;
return res;
}
inline void print(){
for (int i = 1; i <= sec[len]; ++i){
printf("NOW VIEWING SECTION OF %d-%d, id=%d:\n", left(i), right(i), i);
printf("\tThe sum of each element: "); for (int j = left(i); j <= right(i); ++j) printf("%7lld", sum[j]);
puts(""); printf("\t The section sum: %lld\n", secsum[i]);
printf("\t The add tag and the mul tag are: %lld %lld\n", atag[i], mtag[i]);
puts("");
}
puts("");
return;
}
};
int n, m, pp;
Partitioning p;
int main(){
freopen("3373.in", "r", stdin);
freopen("3373.out", "w", stdout);
scanf("%d%d%d", &n, &m, &pp);
p.setup(n);
int op, x, y; ll k;
for (int i = 1; i <= m; ++i){
scanf("%d%d%d", &op, &x, &y);
if (op == 1){
scanf("%lld", &k);
p.mul(x, y, k % MOD);
}
else if (op == 2){
scanf("%lld", &k);
p.add(x, y, k % MOD);
}
else printf("%lld\n", p.query(x, y) % MOD);
printf("OPERATION %d, info:\n", i);
p.print();
}
return 0;
}