题意大概是有求多少个不包含关键点的边长为整数的正方形。
转化一下就是求对于每个点 (x,y) ,以它为左上角的不包括关键点的正方形的边长最大值,令为 f(x,y)
答案就是 ∑f(x,y)
考虑对于每条对角线上的点单独处理
设当前点为 (i,j) ,设 i′ 是最小的满足 (i′,j) 为关键点且 i′>i 的值, j′ 是最小的满足 (i,j′) 为关键点且 j′>j 的值(如果不存在就为无穷大),那么 f(i,j)=min{f(i+1,j+1)+1,j′−j,i′−i}
这样可以 O(n2) 搞,但实际上有用的点只有 O(B) 个,所以只要在这 O(B) 个点之间转移就好了
O(NBlogB)
实际上 log B 很小,所以是可以过的
也可以通过一些手段去掉这个log
还有一个问题就是求
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int N=1010;
int l,w,n,x[N],y[N];
struct Pt{
int x,y,d,r;
Pt(int _x=0,int _y=0,int _d=0,int _r=0):x(_x),y(_y),d(_d),r(_r){}
friend bool operator <(const Pt &a,const Pt &b){
return a.xinline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void rea(int &x){
char c=nc(); x=0;
for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}
Pt p[N];
int id[N],f[N];
ll ans;
inline bool cmp(const int &a,const int &b){
return x[a]int main(){
rea(w); rea(l); rea(n);
for(int i=1;i<=n;i++)
rea(x[i]),rea(y[i]),id[i]=i;
sort(id+1,id+1+n,cmp);
for(int L=-w+1;Lint t=0,cnt;
for(int k=1;k<=n;k++){
int i=id[k];
if(y[i]==L+x[i]){
p[++t]=Pt(x[i],y[i],x[i],y[i]);
}
else if(y[i]>L+x[i]){
if(L+x[i]>0 && L+x[i]<=l)
p[++t]=Pt(x[i],L+x[i],w+1,y[i]);
}
else{
if(y[i]-L>0 && y[i]-L<=w)
p[++t]=Pt(y[i]-L,y[i],x[i],l+1);
}
}
if(w+L<=l) p[++t]=Pt(w,w+L,w+1,w+L+1);
else p[++t]=Pt(l-L,l,l-L+1,l+1);
sort(p+1,p+1+t); cnt=t; t=1;
for(int i=2;i<=cnt;i++)
if(p[i].x==p[i-1].x) p[t].r=min(p[t].r,p[i].r),p[t].d=min(p[t].d,p[i].d);
else p[++t]=p[i];
f[t]=min(p[t].d-p[t].x,p[t].r-p[t].y)-1; p[0]=L<0?Pt(-L,0,-L,0):p[0]=Pt(0,L,0,L);
for(int i=t-1;~i;i--){
f[i]=min(min(p[i].r-p[i].y-1,p[i].d-p[i].x-1),f[i+1]+p[i+1].x-p[i].x);
ans+=(p[i+1].x-p[i].x)*(p[i+1].x-p[i].x-1)/2+(p[i+1].x-p[i].x-1)*f[i+1];
if(f[i]>0) ans+=f[i];
}
}
cout<return 0;
}