Problem Statement

In an $N$-dimensional space, the Manhattan distance $d(x,y)$ between two points $x=(x_1, x_2, \dots, x_N)$ and $y = (y_1, y_2, \dots, y_N)$ is defined by:

\(\displaystyle d(x,y)=\sum_{i=1}^n \vert x_i - y_i \vert.\)

A point $x=(x_1, x_2, \dots, x_N)$ is said to be a lattice point if the components $x_1, x_2, \dots, x_N$ are all integers.

You are given lattice points $p=(p_1, p_2, \dots, p_N)$ and $q = (q_1, q_2, \dots, q_N)$ in an $N$-dimensional space.

How many lattice points $r$ satisfy $d(p,r) \leq D$ and $d(q,r) \leq D$? Find the count modulo $998244353$.

Constraints

  • $1 \leq N \leq 100$
  • $0 \leq D \leq 1000$
  • $-1000 \leq p_i, q_i \leq 1000$
  • All values in input are integers.

Input

Input is given from Standard Input in the following format:

$N$ $D$
$p_1$ $p_2$ $\dots$ $p_N$
$q_1$ $q_2$ $\dots$ $q_N$

Output

Print the answer.


Sample Input 1

1 5
0
3

Sample Output 1

8

When $N=1$, we consider points in a one-dimensional space, that is, on a number line.

$8$ lattice points satisfy the conditions: $-2,-1,0,1,2,3,4,5$.


Sample Input 2

3 10
2 6 5
2 1 2

Sample Output 2

632

Sample Input 3

10 100
3 1 4 1 5 9 2 6 5 3
2 7 1 8 2 8 1 8 2 8

Sample Output 3

145428186

考虑dp,设dp_{i,j,k}表示前 $k$ 位,和串 $p$ 的距离之差为 $i$ ,和串 $q$ 的距离之差为 $j$ 的方案数。
如果把绝对值拆成四种情况来讨论,加上滚动数组,那么可以写出下面这种方法。

#include<bits/stdc++.h>
using namespace std;
const int N=105,M=1005,P=998244353;
int n,d,p[N],q[N],dp[2][M][M],ans;
int main()
{
scanf("%d%d",&n,&d);
for(int i=1;i<=n;i++)
scanf("%d",p+i);
for(int i=1;i<=n;i++)
scanf("%d",q+i);
dp[0][0][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=0;j<=d;j++)
{
for(int k=0;k<=d;k++)
{
dp[i&1][j][k]=0;
for(int l=max(p[i]-j,q[i]-k);l<=min(p[i],q[i]);l++)
{
dp[i&1][j][k]+=dp[i&1^1][j-p[i]+l][k-q[i]+l];
dp[i&1][j][k]%=P;
}
for(int l=max(q[i]-k,p[i]+1);l<=min(q[i]-1,p[i]+j);l++)
{
dp[i&1][j][k]+=dp[i&1^1][j-l+p[i]][k-q[i]+l];
dp[i&1][j][k]%=P;
}
for(int l=max(q[i]+1,p[i]-j);l<=min(p[i]-1,q[i]+k);l++)
{
dp[i&1][j][k]+=dp[i&1^1][j-p[i]+l][k-l+q[i]];
dp[i&1][j][k]%=P;
}
for(int l=max(p[i],q[i])+(p[i]==q[i]);l<=min(p[i]+j,q[i]+k);l++)
{
dp[i&1][j][k]+=dp[i&1^1][j-l+p[i]][k-l+q[i]];
dp[i&1][j][k]%=P;
}
if(i==n)
ans=(ans+dp[i&1][j][k])%P;
}
}
}
printf("%d",ans);
}

发现瓶颈在转移,那么就考虑能不能 \(O(1)\) 转移。

在这四种情况中,有两种情况满足后两个下标之和不变,另两种后两个下标之差不变。考虑在这一点的基础上,使用前缀和。

定义 \(f_{i,j}\) 表示在上一位中,后两个下标差为 \(i\),且第二位下标不超过 \(j\) 的所有dp 值之和,\(s_{i,j}\) 表示在上一位中,后两个下标和为 \(i\),且第二位下标不超过 \(j\) 的所有 \(dp\) 值之和。那么我们在更新 dp 值时分情况用 \(f\) 和 \(s\) 去更新就好了。

代码有些繁琐

#include<bits/stdc++.h>
using namespace std;
const int N=105,M=4005,P=998244353;
int n,d,p[N],q[N],dp[M>>2][M>>2],ans,s[M][M],f[M<<1][M],l,r;
int mo(int x)
{
return (x%P+P)%P;
}
int main()
{
scanf("%d%d",&n,&d);
for(int i=1;i<=n;i++)
scanf("%d",p+i);
for(int i=1;i<=n;i++)
scanf("%d",q+i);
dp[0][0]=1;
for(int j=0;j<=d;j++)
{
for(int k=0;k<=d;k++)
{
f[j-k+M][j+1]=f[j-k+M][j]+dp[j][k];
f[j-k+M][j+1]%=P;
s[j+k][j+1]=s[j+k][j]+dp[j][k];
s[j+k][j+1]%=P;
}
}
for(int i=1;i<=n;i++)
{
for(int j=0;j<=d;j++)
{
for(int k=0;k<=d;k++)
{
dp[j][k]=0;
l=max(p[i]-j,q[i]-k),r=min(p[i],q[i]);
if(l<=r)
dp[j][k]=mo(f[j-k-p[i]+q[i]+M][j-p[i]+r+1]-f[j-k-p[i]+q[i]+M][j-p[i]+l]);
dp[j][k]=mo(dp[j][k]);
l=max(q[i]-k,p[i]+1),r=min(q[i]-1,p[i]+j);
if(l<=r)
dp[j][k]+=mo(s[j+k+p[i]-q[i]][j-l+p[i]+1]-s[j+k+p[i]-q[i]][j-r+p[i]]);
dp[j][k]=mo(dp[j][k]);
l=max(q[i]+1,p[i]-j),r=min(p[i]-1,q[i]+k);
if(l<=r)
dp[j][k]+=mo(s[j+k+q[i]-p[i]][j-p[i]+r+1]-s[j+k+q[i]-p[i]][j-p[i]+l]);
dp[j][k]=mo(dp[j][k]);
l=max(p[i],q[i])+(p[i]==q[i]),r=min(p[i]+j,q[i]+k);
if(l<=r)
dp[j][k]+=mo(f[j-k+p[i]-q[i]+M][j-l+p[i]+1]-f[j-k+p[i]-q[i]+M][j-r+p[i]]);
dp[j][k]=mo(dp[j][k]);
if(i==n)
ans=(ans+dp[j][k])%P;
}
}
for(int j=0;j<=d;j++)
{
for(int k=0;k<=d;k++)
{
f[j-k+M][j+1]=f[j-k+M][j]+dp[j][k];
f[j-k+M][j+1]%=P;
s[j+k][j+1]=s[j+k][j]+dp[j][k];
s[j+k][j+1]%=P;
}
}
}
printf("%d",ans);
}

[ABC265F] Manhattan Cafe的更多相关文章

  1. robotium(及百度cafe)运行testcase之后程序挂起没有响应的原因调查及解决

    一.问题背景 刚开始用的是百度cafe搭建的框架,已经用了一些版本,最后的test版本在7.4的apk上能跑,但是在最新发布的7.5的版本上跑不了,直接提示nullPointer错误,通过打日志的方式 ...

  2. R语言画全基因组关联分析中的曼哈顿图(manhattan plot)

    1.在linux中安装好R 2.准备好画曼哈顿图的R脚本即manhattan.r,manhattan.r内容如下: #!/usr/bin/Rscript #example : Rscript plot ...

  3. Manhattan distance(for lab)

    Input four integer x1, y1, x2, y2, which is mean that the coordinates of two points A(x1, y1), B(x2, ...

  4. bzoj 3170 manhattan距离

    首先将坐标系顺时针旋转45度,得到一个新的坐标系,这个坐标系 对应的坐标的manhattan距离就是原图中的距离,然后快排,利用前缀和 数组O(N)求所有的答案,然后找最小值就行了,总时间O(Nlog ...

  5. GWAS: 曼哈顿图,QQ plot 图,膨胀系数( manhattan、Genomic Inflation Factor)

    画曼哈顿图和QQ plot 首推R包“qqman”,简约方便.下面具体介绍以下. 一.画曼哈顿图 install.packages("qqman") library(qqman) ...

  6. 基于Manhattan最小生成树的莫队算法

    点u,v的Manhattan距离:distance(u,v)= |x2-x1|+|y2-y1| Manhattan最小生成树:边权值为两个点Manhattan距离的最小生成树. 普通算法:prim复杂 ...

  7. manhattan plots in qqplot2

    ###manhattan plots in qqplot2library(ggplot2)setwd("~/ncbi/zm/XPCLR/")read.table("LW. ...

  8. CAFE: a computational tool for the study of gene family evolution

    1.摘要 摘要:我们提出了CAFE(计算分析基因家族进化),这是一个统计分析基因家族进化规模的工具.它使用随机的出生和死亡过程来模拟一个系统发育过程中基因家族大小的进化.对于一个特定的系统发育树,并给 ...

  9. 百度Cafe原理--Android自动化测试学习历程

    主要讲解内容及笔记: 一.Cafe原理 Cafe是一款自动化测试框架,解决问题:跨进程测试.快速深度测试 官网:http://baiduqa.github.io/Cafe/ Cafe provides ...

  10. codechef FEB19 Manhattan Rectangle

    Manhattan Rectangle 链接 题意: 交互题,询问小于7次,确定一个矩形的位置,每次询问一个点到矩形的曼哈顿距离. 分析: 询问三个顶点,然后解一下方程,求出一个边界,就好办了. 用s ...

随机推荐

  1. quarkus数据库篇之四:本地缓存

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<quarkus数据库篇> ...

  2. Windows 虚拟地址 到底是如何映射到 物理地址 的?

    一:背景 1. 讲故事 我发现有很多的 .NET程序员 写了很多年的代码都没弄清楚什么是 虚拟地址,更不用谈什么是 物理地址 以及Windows是如何实现地址映射的了?这一篇我们就来聊一聊这两者之间的 ...

  3. skynet的timer似乎有问题

    skynet.timeout 传进去 number 范围内的数值但是会溢出, 调查发现 skynet.timeout 调用的是 c 的方法: c.intcommand("TIMEOUT&qu ...

  4. To_Heart—题解——好多好多!

    1.CF1860D link && submission 发现自己并不会处理纯纯的 dp 甚至自己根本不会dp! 定义 dp_{i,j,k} 状态表示前 i 个字符有 j 个 0, 0 ...

  5. linux下查找文件中某字符串出现的行以及该行前后n行

    linux下查找文件中某字符串出现的行以及该行前后n行 查找指定字符串的前后n行 grep -A 100 -B 100 "要查找的字符串" 被查找的文件 -A after 后面 - ...

  6. 2023-10-04:用go语言,现有一棵无向、无根的树,树中有 n 个节点,按从 0 到 n - 1 编号 给你一个整数 n 和一个长度为 n - 1 的二维整数数组 edges , 其中 edge

    2023-10-04:用go语言,现有一棵无向.无根的树,树中有 n 个节点,按从 0 到 n - 1 编号 给你一个整数 n 和一个长度为 n - 1 的二维整数数组 edges , 其中 edge ...

  7. Python基础——二分法、面向过程编程思想、有名函数、lambda、max、_min的应用、sorted排序、map的应用、filter的应用、reduce的应用

    文章目录 内容回顾 二分法 伪代码模板 面向过程编程思想 函数式 def用于定义有名函数 lambda用于定义匿名函数 调用匿名函数 匿名函数作用 匿名函数的示范 max的应用 min的应用 sort ...

  8. 基于 Angular和Material autocomplete组件再封装的可双向绑定key-value的可输入下拉框

    GitHub: https://github.com/Xinzheng-Li/AngularCustomerComponent 效果图:为了方便使用,把许多比如ADD的功能去了,可以在使用后自行实现. ...

  9. 可视化-vscode安装pandas

    pandas 是基于NumPy 的一种工具,该工具是为解决数据分析任务而创建的.Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具.pandas提供了大量能使我们快速 ...

  10. k8s-单节点升级为集群(高可用)

    单master节点升级为高可用集群 对于生产环境来说,单节点master风险太大了. 非常有必要做一个高可用的集群,这里的高可用主要是针对控制面板来说的,比如 kube-apiserver.etcd. ...