P1884题解
题目链接
蒟蒻最近刚学差分,考虑用差分做。 看到1e8的范围,直接枚举T飞,所以离散化(接下来有提到)
(一)二维差分
刚拿到手:这不是二维差分修改的裸题吗?根据差分式子:
不过这题不需要,因为初始化都是0,所以d也是0。 修改操作:
到这里,假如你能注意到一个细节,题目的坐标并不知真正的左上角和右下角,这里做一下处理,那么恭喜你,
分别为离散化前后。发现中间空出一部分未染色,而我们的操作将它染色了!
如何处理:
考虑讲二维前缀和降维打击,变成一维前缀和然后暴力枚举每一行,和二维效果一样。这样的好处就在于可以更方便的(或许二维也可以?会的大佬指点一下)修改每一次操作的边界,让他的右边和下面向内缩,这样原来刚好到现在也不会少,原来少的现在就由于多了一空无法算进答案了。
(女少口阿)
附上代码:
#include<bits/stdc++.h>
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define repp(i, a, b) for(int i = a; i >= b; i--)
#define ll long long
using namespace std;
ll N;
ll l[1011][4];
ll a[4011], c[4011];
ll f[4011][4011];
int cnta, cntc;
ll ans;
int main(){
// freopen("f.in","r",stdin);
// freopen("f.out","w",stdout);
scanf("%lld",&N);
rep(i, 1, N){
scanf("%lld%lld%lld%lld",&l[i][0], &l[i][1], &l[i][2], &l[i][3]);
rep(j, 0, 3) a[++cnta] = l[i][j];
}
sort(a + 1, a + cnta + 1);
a[0] = -1;
rep(i, 1, cnta)if(a[i] != a[i - 1])c[++cntc] = a[i];
rep(i, 1, N){
rep(j, 0, 3){
l[i][j] = lower_bound(c + 1, c + cntc + 1, l[i][j]) - c;
}
}
rep(i, 1, N){
rep(j, l[i][0], l[i][2]-1){
f[j][l[i][3]]++; f[j][l[i][1]]--;
}
}
rep(i, 1, cntc){
rep(j, 1, cntc){
f[i][j] += f[i][j - 1];
}
}
rep(i, 1, cntc - 1){
rep(j, 1, cntc - 1){
if(f[i][j]){
ans += (long long)((c[i + 1] - c[i]) * (c[j + 1] - c[j]));
}
}
}
printf("%lld",ans);
return 0;
}
又用二维做了一遍。。。(好像更方便。。打脸)思路一样,不多解释了,代码:
#include<bits/stdc++.h>
#define ll long long
#define rep(i, a, b) for(int i = a; i <= b; i++)
#define repp(i, a, b) for(int i = a; i >= b; i--)
using namespace std;
int N;
ll x11[1011], y11[1011];
ll x2[1011], y2[1011];
ll a[4011], c[4011];
int delta[4011][4011];
int f[4011][4011];
int cnta, cntc;
ll ans;
int main(){
scanf("%d",&N);
rep(i, 1, N){
scanf("%lld%lld%lld%lld",&x11[i], &y11[i], &x2[i], &y2[i]);
x11[i] += 1e7;y11[i] += 1e7;x2[i] += 1e7;y2[i] += 1e7;
a[++cnta] = x11[i];a[++cnta] = y11[i];a[++cnta] = x2[i];a[++cnta] = y2[i];
}
stable_sort(a + 1, a + cnta + 1);
a[0] = -66666666;
rep(i, 1, 4 * N)if(a[i] != a[i - 1])c[++cntc] = a[i];
rep(i, 1, N){
int xx1 = lower_bound(c + 1, c + cntc + 1, x11[i]) - c;
int yy1 = lower_bound(c + 1, c + cntc + 1, y11[i]) - c;
int xx2 = lower_bound(c + 1, c + cntc + 1, x2[i]) - c;
int yy2 = lower_bound(c + 1, c + cntc + 1, y2[i]) - c;
delta[xx2 - 1][yy2]++;//主要是这里
delta[xx2 - 1][yy1]--;
delta[xx1 - 1][yy2]--;
delta[xx1 - 1][yy1]++;
}
repp(i, cntc, 1){
rep(j, 1, cntc){
f[i][j] = f[i + 1][j] + f[i][j - 1] - f[i + 1][j - 1] + delta[i][j];//递推公式
}
}
rep(i, 1, cntc - 1){
rep(j, 1, cntc - 1){
if(f[i][j]){
ans += (long long)((c[i + 1] - c[i]) * (c[j + 1] - c[j]));
}
}
}
printf("%lld",ans);
return 0;
}