题解:P5476 [CCO 2015] 挖掘
分析
先考虑维护出所有
对于颜色数量,枚举出现了哪几个,容斥系数为
对于第一次包含某个蛋的时间,维护出每个点第一次有蛋的时间。然后滑动窗口跑两遍。时间复杂度
最后树状树组一下做到
代码
const int N = 2505, M = 1e5 + 10;
int n, k, m, t;
vector<pii> c;
int delt[N][N], val[N][N];
int mn[N][N], mn_[N][N];
int tim[N][N];
struct node{
int op, x, y;
} q[M];
int qu[N], hh, tt;
vector<int> vec[M];
int tr[N * N];
il void add(int x, int y){
++ x;
while(x) tr[x] += y, x -= x & (-x);
return ;
}
il int qry(int x){
++ x; int res = 0;
while(x < N * N) res += tr[x], x += x & (-x);
return res;
}
il void solve(){
n = rd, k = rd, m = rd;
U(i, 1, m){
int x = rd; c.clear();
U(j, 1, x) c.push_back({rd, rd});
for(auto [x, y]: c) assert(x <= n && y <= n);
U(s, 1, (1 << x) - 1){
int xmi = n + 1, ymi = n + 1, xmx = 0, ymx = 0;
UU(j, 0, x) if((s >> j) & 1){
xmi = min(xmi, c[j].x);
xmx = max(xmx, c[j].x);
ymi = min(ymi, c[j].y);
ymx = max(ymx, c[j].y);
}
if(xmx - xmi > k - 1|| ymx - ymi > k - 1) continue;
int cnt = __builtin_popcount(s) - 1, v = 1;
if(cnt & 1) v = -1;
xmx = max(1, xmx - k + 1), ymx = max(1, ymx - k + 1);
delt[xmx][ymx] += v;
delt[xmx][ymi + 1] -= v;
delt[xmi + 1][ymx] -= v;
delt[xmi + 1][ymi + 1] += v;
}
}
t = rd;
U(i, 1, n) U(j, 1, n){
delt[i][j] += delt[i - 1][j] + delt[i][j - 1] - delt[i - 1][j - 1];
val[i][j] = delt[i][j];
mn[i][j] = t + 1;
}
U(i, 1, t){
q[i].op = rd, q[i].x = rd;
if(q[i].op == 1){
q[i].y = rd;
mn[q[i].x][q[i].y] = min(mn[q[i].x][q[i].y], i);
}
}
U(i, 1, n){
hh = 0, tt = 1;
U(j, 1, n){
while(hh <= tt && mn[i][qu[tt]] >= mn[i][j]) -- tt;
qu[++ tt] = j;
while(hh <= tt && qu[hh] < j - k + 1) ++ hh;
mn_[i][j] = mn[i][qu[hh]];
}
}
U(j, k, n){
hh = 0, tt = 1;
U(i, 1, n){
while(hh <= tt && mn_[qu[tt]][j] >= mn_[i][j]) -- tt;
qu[++ tt] = i;
while(hh <= tt && qu[hh] < i - k + 1) ++ hh;
if(i >= k) tim[i - k + 1][j - k + 1] = mn_[qu[hh]][j];
}
}
int cnt = 0;
U(i, 1, n - k + 1) U(j, 1, n - k + 1){
vec[tim[i][j]].push_back(val[i][j]);
++ cnt;
add(val[i][j], 1);
}
U(i, 1, t){
for(auto x: vec[i]){
add(x, -1);
}
if(q[i].op == 2){
int cnt_ = qry(q[i].x);
printf("%.12lf\n", (double)(cnt_ * 1.0 / cnt));
}
}
return ;
}