----------------------------------------------------------
线性分块, 国外通常把块大小为 sqrt(n) 的分块方式叫做 “SQRT Decomposition”。
资料:
《入门经典:训练指南》P395
http://sysmagazine.com/posts/138946/
http://algoacm.com/Algorithms/sqrt_decomposition/sqrt_decomposition.html
题目:
Uva 12003 Array Transformer
#include
using namespace std;
#define SPEED_UP iostream::sync_with_stdio(false);
#define FIXED_FLOAT cout.setf(ios::fixed, ios::floatfield);
#define rep(i, s, t) for(int (i)=(s);(i)<=(t);++(i))
#define urep(i, s, t) for(int (i)=(s);(i)>=(t);--(i))
typedef long long LL;
struct Edge{
int u, v, c;
Edge(){}
Edge(int u, int v, int c):u(u), v(v), c(c){}
int getAdj(int x) {
return x == u ? v : u;
}
};
const int Maxn = 300000;
const int SIZE = 4096;
int n, m, u, a[Maxn+5], block[Maxn/SIZE+5][SIZE], numBlock, numLastBlock;
//#define DEBUG
void init() {
cin >> n >> m >> u;
int b = 0, j = 0;
rep(i, 0, n-1) {
cin >> a[i];
block[b][j] = a[i];
++j;
if (j == SIZE) {++b;j=0;}
}
rep(i, 0, b-1) sort(block[i], block[i]+SIZE);
if (j) sort(block[b], block[b]+j);
numBlock = b;
numLastBlock = j ? j : SIZE;
}
int countOrderedRange(const int * l, const int * r, int v) {
int ret = 0;
for (const int *p=l;p<=r;++p) {
if (*p < v) ++ret;
}
return ret;
}
int Query(int L, int R, int v) {
int lb = L/SIZE, rb = R/SIZE, ret = 0;
rep(i, lb+1, rb-1) {
ret += lower_bound(block[i], block[i]+SIZE, v) - block[i];
}
if (lb == rb) {
ret += countOrderedRange(a+L, a+R, v);
}
else {
ret += countOrderedRange(a+L, a+(lb+1)*SIZE-1, v);
ret += countOrderedRange(a+rb*SIZE, a+R, v);
}
return ret;
}
void Update(int p, int x) {
int * B = block[p/SIZE];
int old = a[p];
a[p] = x;
const int bSize = p/SIZE == numBlock ? numLastBlock : SIZE;
int pos = lower_bound(B, B+bSize, old) - B;
#ifdef DEBUG
cout << "in update: old->" << old << " pos->" << pos << endl;
cout << "Elements in this block: ";
rep(i, 0, bSize-2) cout << B[i] << ' ';cout << B[bSize-1] << endl;
#endif
while (pos > 0 && x < B[pos-1]) {
B[pos] = B[pos-1];
--pos;
}
while (pos < bSize-1 && x > B[pos+1]) {
B[pos] = B[pos+1];
++pos;
}
B[pos] = x;
}
void printBlocks() {
cout << "-------Show Blocks-------" << endl;
rep(i, 0, numBlock-1) {
cout << "Block " << i << ": ";
rep(j, 0, SIZE-2) cout << block[i][j] << ' ';cout << block[i][SIZE-1] << endl;
}
cout << "Block " << numBlock << ": ";
rep(j, 0, numLastBlock-2) cout << block[numBlock][j] << ' ';cout << block[numBlock][numLastBlock-1] << endl;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("input.in", "r", stdin);
#endif
SPEED_UP
init();
//printBlocks();
while (m--) {
int L, R, v, p;
cin >> L >> R >> v >> p;
--L;--R;--p;
int k = Query(L, R, v);
Update(p, u*1ll*k/(R-L+1));
#ifdef DEBUG
cout << "Q: " << L << ' ' << R << ' ' << v << ' ' << p << " k: " << k << endl;
printBlocks();
#endif
}
rep(i, 0, n-1) cout << a[i] << endl;
return 0;
}
hdu 5057 Argestes and Sequence
//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
codeforces 13E - Holes
//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include