安徽师大附中%你赛day9 T2 富 解题报告

题目背景

出于某些原因, 苟先生在追杀富先生。

题目描述

富先生所在的地方是一个\(n\times m\)的网格,苟先生排出了他的狼狗大军,共有\(k\)条狗,第\(i\)条狗所在的位置为\((x_i, y_i)\)。每条狗每个时刻都可以向\(8\)个方向前进一步。

如果一个格子最快的一条狗需要\(t\)时刻才能到,那么这个格子就是\(t\)-危险的,现在给你\(t\),询问有多少个\(t\)-危险的格子。

输入输出格式

输入格式

第一行四个整数\(n,m,k,t\)
接下来\(k\)行每行两个整数\(x_i,y_i\),没有两条狗在同一个位置。

输出格式

一行一个整数表示答案。

说明

对于\(30\%\)的数据\(n,m\le 1000\)

对于另外\(20\%\)的数据\(k\le 50,n\le 1000\)

对于另外\(20\%\)的数据\(k\le 50\)

对于\(100\%\)的数据\(k\le 2000, n, m\le 1000000000, 0\le t\le n+m\)


据老与蒟蒻我的区别
我:

现在19:26 感受一下。。

据老:

据老花了据他所说是一个小时(事实上大概不到40分钟

他第一次交数组开小了

正题

题目要求我们求正方形的外层一圈且不可以在其他正方形的边边上,我们可以转化成求两次面积并做差,一次是\(t*2+1\)边长的,一次是\(t*2-1\)边长的,模拟一下是为什么

然后就是扫描线求面积并了

注意到我们由坐标转换成了格子,所以我们把删除线的坐标右移一位

还有一点就是扫描线本身,因为我们把区间放到了点(作为区间的左端点),所以修改时如果是区间\([l,r]\),则线段树进\([l,r-1]\)


Code:

#include <cstdio>
#include <algorithm>
#include <cstring>
#define ll long long
using namespace std;
const ll N=4e3+10;
ll px[N],py[N],n,m,k;
struct node
{
    ll x,up,dow,k;
    bool friend operator <(node n1,node n2)
    {
        return n1.x==n2.x?n1.k<n2.k:n1.x<n2.x;
    }
}line[N];
ll sum[N<<2],is[N<<2],fy[N],y[N];
#define ls id<<1
#define rs id<<1|1
void updata(ll id,ll l,ll r)
{
    sum[id]=is[id]?y[r+1]-y[l]:sum[ls]+sum[rs];
}
void change(ll id,ll l,ll r,ll L,ll R,ll delta)
{
    if(l==L&&r==R)
    {
        is[id]+=delta;
        updata(id,l,r);
        return;
    }
    ll Mid=L+R>>1;
    if(r<=Mid) change(ls,l,r,L,Mid,delta);
    else if(l>Mid) change(rs,l,r,Mid+1,R,delta);
    else change(ls,l,Mid,L,Mid,delta),change(rs,Mid+1,r,Mid+1,R,delta);
    updata(id,L,R);
}
ll matrix_s(ll t)
{
    memset(sum,0,sizeof(sum)),memset(is,0,sizeof(is));
    ll cnt=0,ans=0;
    for(ll i=1;i<=k;i++)
    {
        y[++cnt]=max(1ll,py[i]-t),y[++cnt]=min(m+1,py[i]+t+1);
        line[cnt-1]={max(1ll,px[i]-t),y[cnt-1],y[cnt],1};
        line[cnt]={min(n+1,px[i]+t+1),y[cnt-1],y[cnt],-1};
    }
    sort(y+1,y+cnt+1),sort(line+1,line+cnt+1);
    cnt=unique(y+1,y+cnt+1)-(y+1);
    for(ll l,r,i=1;i<k<<1;i++)
    {
        l=lower_bound(y+1,y+1+cnt,line[i].up)-y;
        r=lower_bound(y+1,y+1+cnt,line[i].dow)-y-1;
        change(1,l,r,1,cnt,line[i].k);
        ans+=sum[1]*(line[i+1].x-line[i].x);
    }
    return ans;
}
int main()
{
    ll t;
    scanf("%lld%lld%lld%lld",&n,&m,&k,&t);
    for(ll i=1;i<=k;i++) scanf("%lld%lld",px+i,py+i);
    printf("%lld\n",matrix_s(t)-matrix_s(t-1));
    return 0;
}


2018.8.31

posted @ 2018-08-31 19:36  露迭月  阅读(126)  评论(0编辑  收藏  举报