hdu4698 Counting

来源:互联网 发布:编辑歌曲的软件 编辑:程序博客网 时间:2024/05/17 09:30

解法:通过Xmin,Xmax和Ymin,Ymax得出的一个范围可以看成一个矩形,所以只要求出所有不包含平面内的点的矩形,然后总数减去这些矩形数即可。

           对于一个空白矩形a*b,他的子矩形个数为a(a+1)/2* b*(b+1)/2.

           要求出所有不符合条件的矩形只需要枚举所有下边界,然后求出所有以这个下边界出发的矩形即可。

#include<stdio.h>#include<set>#include<algorithm>#define LL long longusing 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;}


原创粉丝点击