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. 玩转 PI 系列-看起来像服务器的 ARM 开发板矩阵-Firefly Cluster Server

    前言 基于我个人的工作内容和兴趣,想要在家里搞一套服务器集群,用于容器/K8s 等方案的测试验证. 考虑过使用二手服务器,比如 Dell R730, 还搞了一套配置清单,如下: Dell R730 3 ...

  2. Python条件控制和循环语句(if while for )

    Python条件控制和循环语句(if while for ) 条件控制 概念:Python 条件语句是通过一条或多条语句的执行结果(True 或者 False)来决定执行的代码块 结构 1. 顺序结构 ...

  3. 文心一言 VS 讯飞星火 VS chatgpt (87)-- 算法导论8.2 4题

    四.用go语言,设计一个算法,它能够对于任何给定的介于0到 k 之间的 n 个整数先进行预处理,然后在 O(1)时间内回答输入的 n个整数中有多少个落在区间[a..b]内.你设计的算法的预处理时间应为 ...

  4. Nomad系列-Nomad网络模式

    系列文章 Nomad 系列文章 概述 Nomad 的网络和 Docker 的也有很大不同, 和 K8s 的有很大不同. 另外, Nomad 不同版本(Nomad 1.3 版本前后)或是否集成 Cons ...

  5. ATtiny88初体验(七):TWI

    ATtiny88初体验(七):TWI TWI模块介绍 ATtiny88的TWI模块兼容Phillips I2C以及SMBus,支持主从模式,支持7bit地址,最大允许128个不同的从机地址.在多主机模 ...

  6. 如何在kubernetes中实现分布式可扩展的WebSocket服务架构

    如何在kubernetes中实现分布式可扩展的WebSocket服务架构 How to implement a distributed and auto-scalable WebSocket serv ...

  7. 循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(5) -- 树列表TreeView的使用

    在我们展示一些参考信息的时候,有所会用树形列表来展示结构信息,如对于有父子关系的多层级部门机构,以及一些常用如字典大类节点,也都可以利用树形列表的方式进行展示,本篇随笔介绍基于WPF的方式,使用Tre ...

  8. Oracle CloudWorld 2022 - 使用Oracle MAA实现应用程序的连续可用性

    每每谈到Oracle MAA,大家条件反射般就会想到Oracle的RAC和ADG等核心选件,当然,这些技术有口皆碑,也的确是MAA的构建基础,但本文我们不再过多谈这些耳熟能详的技术,而是来跟大家探讨下 ...

  9. JAVA实现单链表修改和删除数据节点

    JAVA实现单链表修改和删除数据节点 一.修改单链表中的一个节点 ①实现思路 因为带头节点的链表中头节点的next域不能发生改变(始终指向单链表的头节点),否则将找不到该链表.所以我们需要先找一个辅助 ...

  10. Bridge 桥接模式简介与 C# 示例【结构型2】【设计模式来了_7】

    〇.简介 1.什么是桥接模式? 一句话解释:   通过一个类的抽象,与另一个类的抽象关联起来,当做桥.此后不管两个抽象类的实现有多少种,均可以通过这个桥来将两个对象联系起来. 桥接,顾名思义就是用桥来 ...