LOJ 分块入门:
1. 分块入门 1
#include<bits/stdc++.h>
using namespace std;
const int N = 5e4 + 100;
int n, blo, a[N], b[N], tag[N];
void modify(int l, int r, int c) {
for (int i = l; i <= min(r, b[l]*blo); ++i)
a[i] += c;
if (b[l] != b[r])
for (int i = (b[r] - 1) * blo + 1; i <= r; ++i)
a[i] += c;
for (int i = b[l] + 1; i <= b[r] - 1; ++i)
tag[i] += c;
}
int main() {
int opt, l, r, c;
scanf("%d", &n);
blo = sqrt(n);
for (int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
for (int i = 1; i <= n; ++i)
b[i] = (i - 1) / blo + 1;
for (int i = 0; i < n; ++i) {
scanf("%d%d%d%d", &opt, &l, &r, &c);
if (opt == 0) {
modify(l, r, c);
} else {
printf("%d\n", a[r] + tag[b[r]]);
}
}
return 0;
}
1. 分块入门2
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 100;
int n, m, blo, bl[N], a[N], tag[N], id[N];
int ans;
vector<int>vec[510];
void reset(int x) {
vec[x].clear();
for (int i = (x - 1) * blo + 1; i <= min(x * blo, n); ++i)
vec[x].push_back(a[i]);
sort(vec[x].begin(), vec[x].end());
}
void modify(int x, int y, int z) {
for (int i = x; i <= min(y, bl[x]*blo); ++i)
a[i] += z;
reset(bl[x]);
if (bl[x] != bl[y]) {
for (int i = (bl[y] - 1) * blo + 1; i <= y; ++i)
a[i] += z;
reset(bl[y]);
}
for (int i = bl[x] + 1; i <= bl[y] - 1; ++i)
tag[i] += z;
}
int query(int x, int y, int z) {
int ans = 0;
for (int i = x; i <= min(y, (bl[x]*blo)); ++i)
if (a[i] + tag[bl[x]] < z) ans++;
if (bl[x] != bl[y])
for (int i = (bl[y] - 1) * blo + 1; i <= y; ++i)
if (a[i] + tag[bl[y]] < z) ans++;
for (int i = bl[x] + 1; i <= bl[y] - 1; ++i) {
ans += lower_bound(vec[i].begin(), vec[i].end(), z - tag[i]) - vec[i].begin();
}
return ans;
}
int main() {
int opt, x, y, z;
scanf("%d", &n);
blo = sqrt(n); //这个是每块的个数,并不是块数.
for (int i = 1; i <= n; ++i) bl[i] = (i - 1) / blo + 1;
for (int i = 1; i <= n; ++i)
scanf("%d", &a[i]);
for (int i = 1; i <= bl[n]; ++i)
reset(i);
for (int i = 0; i < n; ++i) {
scanf("%d%d%d%d", &opt, &x, &y, &z);
if (opt == 0) {
modify(x, y, z);
} else {
printf("%d\n", query(x, y, z * z));
}
}
return 0;
}
3. 分块入门
#include<bits/stdc++.h>
using namespace std;
ll read() {
ll 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, blo;
int v[100005], bl[100005], atag[100005];
set<int>st[105];
void add(int a, int b, int c) {
for(int i = a; i <= min(bl[a]*blo, b); i++) {
st[bl[a]].erase(v[i]);
v[i] += c;
st[bl[a]].insert(v[i]);
}
if(bl[a] != bl[b]) {
for(int i = (bl[b] - 1) * blo + 1; i <= b; i++) {
st[bl[b]].erase(v[i]);
v[i] += c;
st[bl[b]].insert(v[i]);
}
}
for(int i = bl[a] + 1; i <= bl[b] - 1; i++)
atag[i] += c;
}
int query(int a, int b, int c) {
int ans = -1;
for(int i = a; i <= min(bl[a]*blo, b); i++) {
int val = v[i] + atag[bl[a]];
if(val < c)ans = max(val, ans);
}
if(bl[a] != bl[b])
for(int i = (bl[b] - 1) * blo + 1; i <= b; i++) {
int val = v[i] + atag[bl[b]];
if(val < c)ans = max(val, ans);
}
for(int i = bl[a] + 1; i <= bl[b] - 1; i++) {
int x = c - atag[i];
set<int>::iterator it = st[i].lower_bound(x);
if(it == st[i].begin())continue;
--it;
ans = max(ans, *it + atag[i]);
}
return ans;
}
int main() {
n = read();
blo = 1000;
for(int i = 1; i <= n; i++)v[i] = read();
for(int i = 1; i <= n; i++) {
bl[i] = (i - 1) / blo + 1;
st[bl[i]].insert(v[i]);
}
for(int i = 1; i <= n; i++) {
int f = read(), a = read(), b = read(), c = read();
if(f == 0)add(a, b, c);
if(f == 1)printf("%d\n", query(a, b, c));
}
return 0;
}
4.分块入门
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 100;
int b[N], blo;
long long tag[N], a[N], sum[N];
int n, m;
void modify(int x, int y, int z) {
for (int i = x; i <= min(y, b[x] * blo); ++i) {
a[i] += z;
sum[b[x]] += z;
}
if (b[x] != b[y])
for (int i = (b[y] - 1) * blo + 1; i <= y; ++i) {
a[i] += z;
sum[b[y]] += z;
}
for (int i = b[x] + 1; i <= b[y] - 1; ++i) tag[i] += z;
}
long long query(int x, int y, int z) {
long long ans = 0;
for (int i = x; i <= min(y, b[x] * blo); ++i) ans = (ans + a[i] + tag[b[x]]) % z;
if (b[x] != b[y])
for (int i = (b[y] - 1) * blo + 1; i <= y; ++i) ans = (ans + a[i] + tag[b[y]]) % z;
for (int i = b[x] + 1; i <= b[y] - 1; ++i) ans = ans + sum[i] + tag[i] * blo;
return ans % z;
}
int main() {
int op, x, y, z;
scanf("%d", &n);
blo = sqrt(n);
for (int i = 1; i <= n; ++i) {
scanf("%lld", &a[i]);
b[i] = (i - 1) / blo + 1;
sum[b[i]] += a[i];
}
for (int i = 0; i < n; ++i) {
scanf("%d%d%d%d", &op, &x, &y, &z);
if (op == 0)
modify(x, y, z);
if (op == 1)
printf("%lld\n", query(x, y, z + 1));
}
return 0;
}
5.分块入门
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 100;
int a[N], blo, b[N], n, m;
long long sum[N];
void sovle(int x) {
if (sum[x] == blo) return;
sum[x] = 0;
for (int i = (x - 1) * blo + 1; i <= x*blo; ++i) {
a[i] = sqrt(a[i]), sum[x] += a[i];
}
}
void modify(int x, int y, int z) {
for (int i = x; i <= min(y, b[x]*blo); ++i) {
sum[b[x]] -= a[i];
a[i] = sqrt(a[i]);
sum[b[x]] += a[i];
}
if (b[x] != b[y])
for (int i = (b[y] - 1) * blo + 1; i <= y; ++i) {
sum[b[y]] -= a[i];
a[i] = sqrt(a[i]);
sum[b[y]] += a[i];
}
for (int i = b[x] + 1; i <= b[y] - 1; ++i)
sovle(i);
}
long long query(int x, int y, int z) {
long long ans = 0;
for (int i = x; i <= min(y, b[x]*blo); ++i)
ans += a[i];
if (b[x] != b[y])
for (int i = (b[y] - 1) * blo + 1; i <= y; ++i)
ans += a[i];
for (int i = b[x] + 1; i <= b[y] - 1; ++i)
ans += sum[i];
return ans;
}
int main() {
int op, x, y, z;
scanf("%d", &n);
blo = sqrt(n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
b[i] = (i - 1) / blo + 1;
sum[b[i]] += a[i];
}
for (int i = 0; i < n; ++i) {
scanf("%d%d%d%d", &op, &x, &y, &z);
if (op == 0) modify(x, y, z);
if (op == 1) printf("%lld\n", query(x, y, z));
}
return 0;
}
6.分块入门
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 100;
typedef pair<int, int> P;
int n, m, blo, a[N], b[N << 1], tp;
vector<int>v[5000];
pair<int, int> query(int x) {
for (int i = 1; i <= m; ++i)
if(x > v[i].size()) x -= v[i].size();
else {
return P(i, x - 1);
}
}
void rebuild() {
tp = 0;
for (int i = 1; i <= m; ++i) {
int len = v[i].size();
for (int j = 0; j < len; ++j)
b[++tp] = v[i][j];
v[i].clear();
}
int blo1 = sqrt(tp);
m = (tp - 1) / blo1 + 1;
for (int i = 1; i <= tp; ++i)
v[(i - 1) / blo1 + 1].push_back(b[i]);
}
void modify(int x, int y, int z) {
P t = query(x);
v[t.first].insert(v[t.first].begin() + t.second, y);
if (v[t.first].size() > 20 * blo) rebuild();
}
int main() {
int op, x, y, z;
scanf("%d", &n);
blo = sqrt(n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
v[(i - 1) / blo + 1].push_back(a[i]);
}
m = (n - 1) / blo + 1;
for (int i = 1; i <= n; ++i) {
scanf("%d%d%d%d", &op, &x, &y, &z);
if(op == 0) modify(x, y, z);
if(op == 1) {
P t = query(y);
printf("%d\n", v[t.first][t.second]);
}
}
return 0;
}
7.分块入门
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+100;
const int mod = 10007;
int blo, b[N],n;
long long mul[N],add[N],sum[N],a[N];
void modify(int x, int y, int mm, int aa){
for (int i = (b[x] - 1) * blo + 1; i <= b[x]*blo; ++i)
a[i] = (a[i]*mul[b[x]] + add[b[x]]) % mod;
mul[b[x]] = 1; add[b[x]] = 0;
for (int i = x; i <= min(y, b[x]*blo); ++i)
a[i] = (a[i]*mm + aa) % mod;
if (b[x] != b[y]){
for (int i = (b[y]-1)*blo + 1; i <= b[y]*blo; ++i)
a[i] = (a[i]*mul[b[y]] + add[b[y]]) % mod;
mul[b[y]] = 1, add[b[y]] = 0;
for (int i = (b[y]-1)*blo + 1; i <= y; ++i)
a[i] = (a[i] * mm + aa) % mod;
}
for (int i = b[x] + 1; i <= b[y] -1; ++i){
mul[i] = (mul[i] * mm) % mod;
add[i] = (add[i] * mm + aa) % mod;
}
}
long long query(int x){
return (1ll*a[x] * mul[b[x]] + add[b[x]])%mod;
}
int main(){
int op,x,y,z;
scanf("%d",&n);
blo = sqrt(n);
for (int i = 1; i <= n; ++i){
scanf("%lld",&a[i]);
b[i] = (i - 1)/ blo + 1;
mul[i] = 1;
}
for (int i = 0; i < n; ++i){
scanf("%d%d%d%d",&op, &x,&y,&z);
if (op == 0) modify(x,y,1,z);
if (op == 1) modify(x,y,z,0);
if (op == 2) printf("%lld\n",query(y));
}
return 0;
}