WAd的不行了, 我的做法式线段树, 先把靶子每q个编号, 再把每p把枪能打到的靶子编号插入线段树, 统计最大值, 不断的插入, 统计, 删除...... 就是不对啊, 求大神路过指导......
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#define pause cout << " press any key to continue...", cin >> chh
#define file_r(x) freopen(x, "r", stdin)
#define file_w(x) freopen(x, "w", stdout)
using namespace std;
int chh;
const int N = 50005, M = 100005;
struct Node {
int u, v;
bool operator < (const Node& arg0) const {
if (u != arg0.u) return u < arg0.u;
return v < arg0.v;
}
} edge[M];
int T, n, m, p, q;
int a[M << 2], b[M << 2], head[N];
Node c[M];
void init(int k, int s, int t) {
int mid = (s + t) >> 1;
a[k] = b[k] = 0;
if (s == t) return;
init(k << 1, s, mid);
init(k << 1 | 1, mid + 1, t);
}
void push_down(int k) {
if (b[k] == 0) return;
a[k << 1] += b[k], b[k << 1] += b[k];
a[k << 1 | 1] += b[k], b[k << 1 | 1] + b[k];
b[k] = 0;
}
void update(int k, int s, int t, int x, int y, int f) {
int mid = (s + t) >> 1;
if (s >= x && t <= y) {
a[k] += f, b[k] += f;
return;
}
push_down(k);
if (y <= mid) update(k << 1, s, mid, x, y, f);
else if (x > mid) update(k << 1 | 1, mid + 1, t, x, y, f);
else {
update(k << 1, s, mid, x, mid, f);
update(k << 1 | 1, mid + 1, t, mid + 1, y, f);
}
a[k] = max(a[k << 1], a[k << 1 | 1]);
}
int main() {
//file_r("in.txt");
//file_w("out.txt");
int i, j, k, h, v, l, r, x, y, e;
double ans;
scanf("%d", &T);
while (T--) {
//cout << "cas= " << ++cas << endl;
scanf("%d%d%d%d", &n, &m, &p, &q);
scanf("%d", &k);
for (i = 0; i < k; i++) scanf("%d%d", &edge[i].u, &edge[i].v);
sort(edge, edge + k);
for (i = 0; i < k; i++) {
v = edge[i].v;
c[i].u = v - q + 1 >= 1 ? v - q + 1 : 1;
c[i].v = v + q - 1 <= m ? v : m - q + 1;
}
e = 1;
for (i = 1; i < k; i++) {
if (edge[i].u != edge[i - 1].u) {
c[e] = c[i], edge[e++] = edge[i];
continue;
}
c[i].u = max(c[i].u, c[i - 1].v + 1);
if (c[i].u <= c[i].v) c[e] = c[i], edge[e++] = edge[i];
}
//puts("Fuck");
//for (i = 0; i < e; i++) printf("%d %d\n", edge[i].u, edge[i].v); pause;
fill(head + 1, head + n + 1, -1);
head[edge[0].u] = 0;
//printf("e= %d", e), pause;
for (i = 1; i < e; i++)
if (edge[i].u != edge[i - 1].u) head[edge[i].u] = i;
//for (i = 0; i < e; i++) printf("%d %d %d\n", edge[i].u, c[i].u, c[i].v);
//for (i = 1; i <= n; i++) printf("%d ", head[i]); pause;
init(1, 1, m - q + 1);
for (i = 1; i < p; i++) {
if (head[i] == -1) continue;
for (j = head[i]; edge[j].u == i && j < e; j++){
update(1, 1, m - q + 1, c[j].u, c[j].v, 1);
// printf("ass= %d %d a[1]= %d", c[j].u, c[j].v, a[1]), pause;
}
}
ans = 0;
for (i = p; i <= n; i++) {
// printf("i= %d %d", i, head[i]), pause;
if (head[i] != -1) {
for (j = head[i]; edge[j].u == i && j < e; j++){
update(1, 1, m - q + 1, c[j].u, c[j].v, 1);
// printf("add= %d %d a[1]= %d", c[j].u, c[j].v, a[1]), pause;
}
}
ans += a[1];
//printf("ans = %d", a[1]), pause;
if (head[i - p + 1] != -1) {
for (j = head[i - p + 1]; edge[j].u == i - p + 1 && j < e; j++)
update(1, 1, m - q + 1, c[j].u, c[j].v, -1);
}
}
ans /= n - p + 1;
printf("%.2lf\n", ans);
}
return 0;
}