bzoj1905: Soldier 士兵控制的棋盘

来源:互联网 发布:js css display 编辑:程序博客网 时间:2024/06/06 05:56

传送门
首先我们大力转换坐标系。
然后我们做一遍扫描线求出矩形面积的交。
然后我们减去在外面的部分,可以发现一定是等腰三角形
在搞一个面积并就可以了
时间复杂度O(NlogN)

#include<cmath>#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#define N 300030#define ll long long using namespace std;ll max(ll x,int y){    return x>y?x:y;}struct Squ{ll x,y,r;}s[N];struct L{    ll x,y1,y2,k;    friend bool operator <(L a,L b){        return a.x<b.x;    }};struct Tri{    ll st,ed;    ll sqr(){        if ((ed-st+1)&1) return (ed-st+2)*((ed-st+1)/2+1)/2;        return (ed-st+3)*((ed-st-1)/2+1)/2;    }    friend bool operator <(Tri a,Tri b){        return a.st<b.st;    }};int n,m,k;struct segment{    int tag[N*4],ans[N*4],p[N];    void clear(){        memset(tag,0,sizeof(tag));        memset(ans,0,sizeof(ans));    }    void update(int k,ll l,ll r){        if (tag[k]>0) ans[k]=r-l;        else ans[k]=ans[k*2]+ans[k*2+1];    }    void add(int k,int l,int r,int x,int y,int v){        int mid=(l+r)/2;        if (x<=p[l]&&p[r]<=y) tag[k]+=v;        else{            if (x<p[mid]) add(k*2,l,mid,x,y,v);            if (p[mid]<y) add(k*2+1,mid,r,x,y,v);        }        update(k,p[l],p[r]);    }    ll ask(){        return ans[1];    }}T;struct calSqu{    L l[N];    int tot,n;    ll x1[N],x2[N],y1[N],y2[N];    ll calc(){        T.clear();        for (int i=1;i<=n;i++)            T.p[i*2-1]=y1[i],T.p[i*2]=y2[i];        sort(T.p+1,T.p+2*n+1);        tot=1;        for (int i=2;i<=2*n;i++)            if (T.p[i]!=T.p[i-1])                T.p[++tot]=T.p[i];        for (int i=1;i<=n;i++){            l[i*2-1]=(L){x1[i],y1[i],y2[i],1};            l[i*2]=(L){x2[i],y1[i],y2[i],-1};         }        sort(l+1,l+2*n+1);        ll ans=0,la=0;        for (int i=1;i<=2*n;i++){            if (i!=1) ans+=la*(ll)(l[i].x-l[i-1].x);            if (l[i].y1!=l[i].y2) T.add(1,1,tot,l[i].y1,l[i].y2,l[i].k);            la=T.ask();        }        return ans;    }}Cal;struct calTri{    int n;    Tri t[N],tmp;    ll calc(){        if (!n) return 0ll;        sort(t+1,t+n+1);        ll ans=t[1].sqr(); int x=1;        for (int i=2;i<=n;i++){            if (t[i].st>=t[x].st&&t[i].ed<=t[x].ed) continue;            if (t[i].st>t[x].ed){                ans+=t[i].sqr(); x=i; continue;            }            ans+=t[i].sqr();            tmp=(Tri){t[i].st,t[x].ed};            ans-=tmp.sqr();            x=i;        }        return ans;    }}Tr;int main(){    scanf("%d%d%d",&n,&m,&k);    for (int i=1;i<=k;i++)        scanf("%lld%lld%lld",&s[i].x,&s[i].y,&s[i].r);    Cal.n=k;    for (int i=1;i<=k;i++){        int tmp=s[i].r-((s[i].x+s[i].y+s[i].r)&1);        Cal.x1[i]=(s[i].y+s[i].x-tmp)/2;        Cal.y1[i]=(s[i].y-s[i].x-tmp)/2;        Cal.x2[i]=(s[i].y+s[i].x+tmp)/2+1;        Cal.y2[i]=(s[i].y-s[i].x+tmp)/2+1;    }    ll ans=Cal.calc();    for (int i=1;i<=k;i++){        int tmp=s[i].r-(!((s[i].x+s[i].y+s[i].r)&1));        Cal.x1[i]=(s[i].y+s[i].x-tmp-1)/2;        Cal.y1[i]=(s[i].y-s[i].x-tmp-1)/2;        Cal.x2[i]=(s[i].y+s[i].x+tmp-1)/2+1;        Cal.y2[i]=(s[i].y-s[i].x+tmp-1)/2+1;    }    ans+=Cal.calc();    Tr.n=0;    for (int i=1;i<=k;i++)        if (s[i].r>=s[i].x){            ++Tr.n;            Tr.t[Tr.n].st=s[i].y-(s[i].r-s[i].x);            Tr.t[Tr.n].ed=s[i].y+(s[i].r-s[i].x);        }    ans-=Tr.calc();    Tr.n=0;    for (int i=1;i<=k;i++)        if (s[i].r>=s[i].y){            ++Tr.n;            Tr.t[Tr.n].st=s[i].x-(s[i].r-s[i].y);            Tr.t[Tr.n].ed=s[i].x+(s[i].r-s[i].y);        }    ans-=Tr.calc();    Tr.n=0;    for (int i=1;i<=k;i++)        if (s[i].r>=n+1-s[i].x){            ++Tr.n;            Tr.t[Tr.n].st=s[i].y-(s[i].r-(n+1-s[i].x));            Tr.t[Tr.n].ed=s[i].y+(s[i].r-(n+1-s[i].x));        }    ans-=Tr.calc();    Tr.n=0;    for (int i=1;i<=k;i++)        if (s[i].r>=m+1-s[i].y){            ++Tr.n;            Tr.t[Tr.n].st=s[i].x-(s[i].r-(m+1-s[i].y));            Tr.t[Tr.n].ed=s[i].x+(s[i].r-(m+1-s[i].y));        }    ans-=Tr.calc();    ll m1=0,m2=0,m3=0,m4=0;    for (int i=1;i<=k;i++){        if (s[i].r>=s[i].x+s[i].y) m1=max(m1,1+s[i].r-s[i].x-s[i].y);        if (s[i].r>=s[i].x+(m+1-s[i].y)) m2=max(m2,1+s[i].r-s[i].x-(m+1-s[i].y));        if (s[i].r>=(n+1-s[i].x)+s[i].y) m3=max(m3,1+s[i].r-(n+1-s[i].x)-s[i].y);        if (s[i].r>=(n+1-s[i].x)+(m+1-s[i].y)) m4=max(m4,1+s[i].r-(n+1-s[i].x)-(m+1-s[i].y));    }    ans+=(m1*m1+m2*m2+m3*m3+m4*m4+m1+m2+m3+m4)/2;    printf("%lld",ans);}
原创粉丝点击