解法:通过Xmin,Xmax和Ymin,Ymax得出的一个范围可以看成一个矩形,所以只要求出所有不包含平面内的点的矩形,然后总数减去这些矩形数即可。
对于一个空白矩形a*b,他的子矩形个数为a(a+1)/2* b*(b+1)/2.
要求出所有不符合条件的矩形只需要枚举所有下边界,然后求出所有以这个下边界出发的矩形即可。
#include<stdio.h>
#include<set>
#include<algorithm>
#define LL long long
using namespace std;
const int mod=1000000000+7;
struct node
{
int x,y,id;
bool operator <(const node &item)const{
return x==item.x?(y<item.y):x<item.x;
}
}f[2222],ff[2222];
int n,m,pre[2222],nxt[2222];
bool cmp(node a,node b)
{
return a.y==b.y?(a.x<b.x):a.y<b.y;
}
set<node>mm;
LL calcu(int s)
{
LL ans=(LL)s*(s+1)/2;
if(ans>=mod)ans%=mod;
return ans;
}
LL modstyle(LL s)
{
if(s>=mod)s%=mod;
return s;
}
int main()
{
int k,i,j;
while(scanf("%d%d%d",&n,&m,&k)!=-1)
{
for(i=0;i<k;i++)scanf("%d%d",&f[i].x,&f[i].y);
sort(f,f+k);
for(i=1,j=1;i<k;i++)
{
if(f[i].x==f[i-1].x&&f[i].y==f[i-1].y)continue;
f[j++]=f[i];
}
k=j;
mm.clear();
for(i=0;i<k;i++)
{
f[i].id=i;ff[i]=f[i];
if(i==0||f[i].x!=f[i-1].x)mm.insert(f[i]);
}
sort(f,f+k,cmp);
for(i=0;i<k;i++)
{
pre[i]=nxt[i]=-1;
for(j=0;j<i;j++)
{
if(f[j].x<f[i].x&&(pre[i]==-1||f[ pre[i] ].x<f[j].x))pre[i]=j;
if(f[j].x>f[i].x&&(nxt[i]==-1||f[ nxt[i] ].x>f[j].x))nxt[i]=j;
}
}
set<node>::iterator it;
int ed,h,st=1,l,r,id,s1,s2;
LL ans=0;
for(i=0;i<k;i++)
{
ed=f[i].y-st;
l=0;r=n+1;
if(i&&f[i-1].y==f[i].y)l=f[i].x;
if(i+1<k&&f[i+1].y==f[i].y)r=f[i+1].x;
if(i==0||f[i].y!=f[i-1].y)ans+=calcu(n)*calcu(ed);
ans=modstyle(ans);
ed++;
for(j=i+1;j<k;j++)
{
if(f[j].x<=l||f[j].x>=r)continue;
id=f[j].id;
if(id&&ff[id-1].x==f[j].x&&(ff[id-1].y>f[i].y||ff[id-1].y==f[i].y&&ff[id-1].x>=f[i].x))continue;
if(nxt[j]==-1){
s2=r-1;h=0;
}
else{
s2=f[ nxt[j] ].x-1;
h=f[ nxt[j] ].y;
}
if(pre[j]==-1){
s1=0;
}
else{
s1=f[ pre[j] ].x;
h=max(h,f[ pre[j] ].y);
}
s2=s2-s1;
h=f[j].y-h;
ans+=calcu(s2)*modstyle((LL)h*ed);
ans=modstyle(ans);
}
node p;
int lastx=l+1,lasty=0;
for(it=mm.begin();it!=mm.end();it++)
{
p=*it;
if(p.x<=l)continue;
if(p.x>=r)break;
h=max(lasty,p.y);
h=m-h+1;
s2=p.x-lastx;
ans+=calcu(s2)*modstyle((LL)h*ed);
ans=modstyle(ans);
lastx=p.x+1;lasty=p.y;
}
it--;
p=*it;
h=m-p.y+1;
s2=r-p.x-1;
ans+=calcu(s2)*modstyle((LL)h*ed);
ans=modstyle(ans);
if(i+1<k&&f[i+1].y!=f[i].y)st=f[i].y+1;
mm.erase(f[i]);
id=f[i].id;
if(id+1<k&&ff[id+1].x==f[i].x)mm.insert(ff[id+1]);
int left=-1,right=-1,flag=0;
for(j=i+1;j<k;j++)
{
if(f[j].x<f[i].x)
{
if(nxt[j]==i)nxt[j]=right;
if(left==-1||f[left].x<f[j].x)left=j;
}
else if(f[j].x>f[i].x)
{
if(pre[j]==i)pre[j]=left;
if(right==-1||f[right].x>f[j].x)right=j;
}
else if(!flag)
{
left=right=j;
flag=1;
}
}
}
ans+=calcu(n)*calcu(m-f[k-1].y);
ans=calcu(n)*calcu(m)-ans;
ans=(ans%mod+mod)%mod;
printf("%I64d\n",ans);
}
return 0;
}