题目链接
- 除了扫描线,二维前缀和也可以O(\(n^2\))地求出矩形的面积并,且两种方法的前提都是离散化
- 二维差分:在矩形的四个顶角做标记,也有容斥原理的影子
- 变量名不能起y1,y2似乎还是C++98时代的事情,打开-std=c++11就没有这个问题了;现在连NOIP都使用C++14标准了,所以应该不用管这种事了,何况编译错误在正式比赛中也不计入罚时
- matrix是矩阵 rectangle才是矩形
- 方法上的根本性错误——推翻【扫描线】理论
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int mod=998244353;
struct r1
{
int x1,y1,x2,y2;
}r[2005];
int n;
int h[8005];
int s[8005][8005];
long long g[2005],raw[8005];
unordered_map<int,int>v;
long long jc[2005],jcinv[2005];
long long c(int n,int m,int opt)
{
if(m>n)
{
return 0;
}
if(opt==1)
{
return jc[n]*jcinv[m]%mod*jcinv[n-m]%mod;
}
return jcinv[n]*jc[m]%mod*jc[n-m]%mod;
}
void pre()
{
jc[0]=1;
for(int i=1;i<=n;i++)
{
jc[i]=jc[i-1]*i%mod;
}
jcinv[n]=power(jc[n],998244351);
for(int i=n-1;i>=0;i--)
{
jcinv[i]=(i+1)*jcinv[i+1]%mod;
}
}
int main()
{
cin>>n;
pre();
for(int i=1;i<=n;i++)
{
cin>>r[i].x1>>r[i].y1>>r[i].x2>>r[i].y2;
h[i]=r[i].x1;
h[i+n]=r[i].y1;
h[i+2*n]=r[i].x2;
h[i+3*n]=r[i].y2;
}
sort(h+1,h+4*n+1);
int m=unique(h+1,h+4*n+1)-(h+1);
for(int i=1;i<=m;i++)
{
raw[i]=h[i];
v[h[i]]=i;
}
for(int i=1;i<=n;i++)
{
s[v[r[i].x1]][v[r[i].y1]]++;
s[v[r[i].x2]][v[r[i].y1]]--;
s[v[r[i].x1]][v[r[i].y2]]--;
s[v[r[i].x2]][v[r[i].y2]]++;
}
for(int i=1;i<=m;i++)
{
s[i][0]+=s[i-1][0];
s[0][i]+=s[0][i-1];
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=m;j++)
{
s[i][j]+=(s[i-1][j]+s[i][j-1]-s[i-1][j-1]);
g[s[i][j]]=(g[s[i][j]]+(raw[i+1]-raw[i])*(raw[j+1]-raw[j])%mod)%mod;
}
}
for(int k=1;k<=n;k++)
{
long long ans=0;
for(int i=1;i<=n;i++)
{
ans=(ans+(c(n,k,1)-c(n-i,k,1)+mod)*c(n,k,-1)%mod*g[i]%mod)%mod;
}
printf("%lld\n",ans);
}
return 0;
}