表格(拉格朗日插值法)

article/2025/10/24 11:41:56

众所周知,Logx精通Excel。
他觉得表格只有单调的白色非常无聊,他决定将一些单元格涂黑。

在一个n行m列的表格里,刚开始所有单元格都是白的。
Logx打算在这个表格选出三个不同的单元格A(x1,y1),B(x2,y2),C(x3,y3),并将选中的三个单元格涂黑。
为了使表格看起来美观,Logx会使每一行和每一列均至多有一个格子被涂黑。
他称一种选择方案是好的,当且仅当L≤|x1-x2|+|y1-y2|+|x2-x3|+|y2-y3|+|x1-x3|+|y1-y3|≤R,即这三个黑格子之间两两的曼哈顿距离之和在区间[L,R]内。其中L,R是他给定的两个常数。
两种方案不同,当且仅当存在一个格子,在一种方案中被涂黑了,在另一种方案中没有被涂黑。
Logx想要知道,有多少种选择方案是好的。
 

输入

输入仅一行,包含四个正整数 n,m,L,R,含义见题目描述。

输出

输出一行一个整数表示方案数。
由于答案可能很大,你只要输出方案数对10^9+7取模的结果。

 

样例输入 Copy

【样例1】
3 3 1 20000
【样例2】
3 3 4 7
【样例3】
4 6 9 12
【样例4】
7 5 13 18
【样例5】
4000 4000 4000 14000

样例输出 Copy

【样例1】
6
【样例2】
0
【样例3】
264
【样例4】
1212
【样例5】
859690013

提示

对于所有数据,3≤n,m≤10^16,1≤L≤R≤10^18。

 

结论:

1. 设三个不在同行同列的黑格子所围成的长方形为x * y,那么三个黑格子两两之间距离和为2 * (x + y - 2);

2. 设三个不在同行同列的黑格子所围成的长方形为x * y,有6 * (x - 2) * (y - 2)种方法放置三个黑格子;

3. 一个大小为x * y的长方形在n * m的格子中有(n - x + 1) * (m - y + 1);

 

首先将(L, R)区间拆成(1,R) - (1, L - 1)

所以

 

 

H1(x)用拉格朗日插值法算出来

H2(x)可以直接用公式或者同第一步用拉格朗日插值

最暴力的代码O(n*m)

/**/
#pragma GCC optimize(3,"Ofast","inline")
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue>typedef long long LL;
using namespace std;const long long mod = 1e9 + 7;LL n, m, l, r;
LL pw6, pw2;LL poww(LL x, LL num){LL res = 1;while(num){if(num & 1) res = res * x % mod;x = x * x % mod;num >>= 1;}return res;
}LL cal(LL x, LL y){return (x - 2) * (y - 2) % mod * 6 % mod;
}LL cal1(LL x){return x * (x + 1) % mod * (2 * x + 1) % mod * pw6 % mod;
}int main()
{//freopen("in.txt", "r", stdin);//freopen("out.txt", "w", stdout);pw6 = poww(6, mod - 2);pw2 = poww(2, mod - 2);scanf("%lld %lld %lld %lld", &n, &m, &l, &r);LL ans = 0;for (LL i = 3; i <= min(r / 2 - 1, n); i++){LL L = max(3LL, (l + 1) / 2 + 2 - i), R = min(2 - i + r / 2, m);for (LL j = L; j <= R; j++){ans += cal(i % mod, j % mod) * ((n - i + 1) % mod) % mod * ((m - j + 1) % mod) % mod;ans %= mod;}}printf("%lld\n", ans);return 0;
}
/**/

暴力代码(n)

/**/
#pragma GCC optimize(3,"Ofast","inline")
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue>typedef long long LL;
using namespace std;const long long mod = 1e9 + 7;LL n, m, l, r;
LL pw6, pw2;LL poww(LL x, LL num){LL res = 1;while(num){if(num & 1) res = res * x % mod;x = x * x % mod;num >>= 1;}return res;
}LL cal(LL x, LL y){return (x - 2) * (y - 2) % mod * 6 % mod;
}LL cal1(LL x){return x * (x + 1) % mod * (2 * x + 1) % mod * pw6 % mod;
}int main()
{//freopen("in.txt", "r", stdin);//freopen("out.txt", "w", stdout);pw6 = poww(6, mod - 2);pw2 = poww(2, mod - 2);scanf("%lld %lld %lld %lld", &n, &m, &l, &r);LL ans = 0;for (LL i = 3; i <= min(r / 2 - 1, n); i++){LL L = max(3LL, (l + 1) / 2 + 2 - i), R = min(2 - i + r / 2, m);LL t1 = (cal1((L - 1) % mod) - cal1(R % mod)) % mod;LL t2 = (m + 3) % mod * ((R - L + 1) % mod) % mod * ((R + L) % mod) % mod * pw2 % mod;LL t3 = 2 * (m + 1) % mod * ((R - L + 1) % mod) % mod;LL t = ((t1 + t2 - t3) % mod + mod) % mod;ans = (ans + t * 6 % mod * ((i - 2) % mod) % mod * ((n - i + 1) % mod) % mod) % mod;}printf("%lld\n", ans);return 0;
}
/**/

AC代码:

/**/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue>typedef long long LL;
using namespace std;const int D = 1e3 + 10;const long long mod = 1e9 + 7;LL n, m, l, r, R, pw2, pw6;
LL a[D], f[D], g[D], p[D], p1[D], p2[D], b[D], h[D][2], C[D];LL poww(LL x, LL num){LL res = 1;while(num){if(num & 1) res = res * x % mod;x = x * x % mod;num >>= 1;}return res;
}void init(int M){f[0] = f[1] = g[0] = g[1] = 1;for (int i = 2; i <= M + 4; i++) f[i] = f[i - 1] * i % mod;g[M + 4] = poww(f[M + 4], mod - 2);for (int i = M + 3; i >= 1; i--) g[i] = g[i + 1] * (i + 1) % mod;
}LL sum(LL x, LL y){return ((x - 2) % mod) * ((y - x + 1) % mod) % mod;
}LL calcn(int d, LL *a, LL n){// a[0].. a[d]  a[n]if(n <= d) return a[n];p1[0] = p2[0] = 1;for (int i = 0; i <= d; i++){LL t = (n - i + mod) % mod;p1[i + 1] = p1[i] * t % mod;}for (int i = 0; i <= d; i++){LL t = (n - d + i + mod) % mod;p2[i + 1] = p2[i] * t % mod;}LL ans = 0;for (int i = 0; i <= d; i++){LL t = g[i] * g[d - i] % mod * p1[i] % mod * p2[d - i] % mod * a[i] % mod;if((d - i) & 1) ans = (ans - t + mod) % mod;else ans = (ans + t) % mod;}return ans;
}LL polysum(LL m, LL *a, LL n){// a[0].. a[m] \sum_{i=0}^{n} a[i]if(n <= m){LL sum = 0;for (int i = 0; i <= n; i++) sum = (sum + a[i]) % mod;return sum;}LL b[D];for (int i = 0; i <= m; i++) b[i] = a[i];b[m + 1] = calcn(m, b, m + 1);for (int i = 1; i <= m + 1; i++) b[i] = (b[i - 1] + b[i]) % mod;return calcn(m + 1, b, n);// m次多项式的和是m+1 次多项式
}LL cal3(LL x){return x * (x + 1) % mod * (2 * x + 1) % mod * pw6 % mod;
}LL solve(LL L, LL R){if(L > R) return 0LL;LL t1 = (cal3((L - 1) % mod) - cal3(R % mod)) % mod;LL t2 = (m + 3) % mod * ((R - L + 1) % mod) % mod * ((R + L) % mod) % mod * pw2 % mod;LL t3 = 2 * (m + 1) % mod * ((R - L + 1) % mod) % mod;LL t = ((t1 + t2 - t3) % mod + mod) % mod;return t;
}LL cal1(LL l, LL r){if(l > r) return 0LL;LL a[15];for (int i = 0; i <= 5; i++) a[i] = sum(l + i, n) * solve(3, R / 2 - l - i + 2) % mod;return polysum(5, a, r - l);
}LL cal2(LL l, LL r){if(l > r) return 0LL;LL a[15];a[0] = 0;for (int i = 0; i <= 2; i++) a[i] = sum(l + i, n) * solve(3, m) % mod;return polysum(2, a, r - l);
}LL cal(LL x){if(!x) return 0LL;LL L1 = x / 2 - m + 2, R1 = min(n, x / 2 - 1);LL L2 = 3, R2 = x / 2 - m + 1;if(R2 < L2) return cal1(max(3LL, L1), R1);else if(R2 >= n) return cal2(L2, min(R2, n));else return cal1(L1, R1) + cal2(L2, R2);
}int main()
{//freopen("in.txt", "r", stdin);//freopen("out.txt", "w", stdout);pw2 = poww(2, mod - 2), pw6 = poww(6, mod - 2);init(1000);scanf("%lld %lld %lld %lld", &n, &m, &l, &r);R = r;LL ans = cal(r);R = l - 1;ans -= cal(l - 1);printf("%lld\n", (ans + mod) % mod * 6 % mod);return 0;
}
/**/

 


http://chatgpt.dhexx.cn/article/MjsjOaN5.shtml

相关文章

[计算机数值分析]拉格朗日插值公式

Spring-_-Bear 的 CSDN 博客导航 实际问题中碰到的函数 f ( x ) f(x) f(x) 是各种各样的&#xff0c;有的表达式很复杂&#xff0c;有的甚至给不出数学式子&#xff0c;只提供了一些离散数据&#xff0c;譬如某些点上的函数值和导数值。 由于问题的复杂性&#xff0c;直接研…

高斯-拉格朗日(Gauss-Legendre )Ⅱ型求积公式 数值分析 勘误 P111

教材信息&#xff1a; 数值分析(第二版) 李红 华中科技大学出版社 Gauss-Legendre Ⅱ型求积公式 [a,b]区间上的3点高斯-拉格朗日&#xff08;Gauss-Legendre&#xff09;复化求积公式 X k 2 X_{k2} Xk2​推导说明 QA为什么复化高斯-拉格朗日(Gauss-Legendre)求积公式不需要像牛…

三个三维矢量叉乘公式(拉格朗日矢量公式)推导(非坐标法)

0 简单情况 先从简单的情况开始推导&#xff0c;考虑三个向量 a ⃗ , b ⃗ , c ⃗ \vec{a},\vec{b},\vec{c} a ,b ,c 在同一个平面&#xff0c;其中 c ⃗ ⊥ a ⃗ \vec{c} \perp \vec{a} c ⊥a &#xff0c;如下图所示&#xff0c;求取 ( a ⃗ b ⃗ ) c ⃗ (\vec{a} \times \…

拉格朗日乘子法 latex手打公式 良心推导

文章目录 拉格朗日乘数法简介等式约束问题明确问题基础知识推导构造求极值 不等式约束问题明确问题问题转化 拉格朗日乘数法 简介 简单概括一下拉格朗日乘子法用来解决具有约束的最值问题。 那么其中主要有两个比较重要的问题需要解决&#xff1a; 等式约束问题不等式约束问…

计算方法学习笔记——插值方法,拉格朗日插值公式

插值方法 插值方法是用来处理和分析数据的方法&#xff0c;所谓插值就是在所给数据的基础上再插入一些所需的值&#xff0c;但这些值不是随便给出的&#xff0c;而是在已有数据的基础上进行分析&#xff0c;给出的近似值。 插值方法要解决的问题 首先当我们遇到一堆数据(如表…

机器学习数学基础二:泰勒公式与拉格朗日

建议如果是大一大二的同学想提前学习机器学习的话可以提前看看我这个专栏的文章&#xff0c;说实话&#xff0c;专门做这个学习机器学习前置知识的博主没多少&#xff0c;至少我当时学的时候没找到多少&#xff0c;不得不学习我很厌恶的一个人讲的课&#xff0c;听得我浑身难受…

拉格朗日插值公式详解

一&#xff0e;线性插值(一次插值&#xff09; 已知函数f(x)在区间[xk ,xk1 ]的端点上的函数值yk f(xk ), yk1 f(xk1 ),求一个一次函数yP1 (x)使得yk f(xk ),yk1 f(xk1 ), 其几何意义是已知平面上两点(xk ,yk ),(xk1 ,yk1 ),求一条直线过该已知两点。 1. 插值函数和插…

【拉格朗日差值法】 公式

拉格朗日插值法 给出对于给定的若n1个点的坐标&#xff08;x0,y0)&#xff0c;(x1,y1)…&#xff0c;(xn,yn)&#xff0c;对应于它们的次数不超过n的拉格朗日多项式只有一个。 应用&#xff1a;给出平面上n1个点&#xff0c;求一条穿过这n1个点的n次多项式&#xff0c;或这个多…

拉格朗日乘子法的分析基础篇

拉格朗日乘子法&#xff08;Lagrange Multiplier)在在求取有约束条件的优化问题时使用的算法。约束条件又分为等式和不等式方法。这里只用等式方法作为例子分析算法的含义原理&#xff08;自己理解的&#xff09;。 首先看拉格朗日的计算式子&#xff1a;L(a, x) f(x) a*g(x…

拉格朗日(Lagrange)插值

问题 给定 n n n 个点&#xff0c;可确定一个多项式 y f ( x ) yf(x) yf(x) &#xff0c;要求确定这个多项式并求出 f ( k ) f(k) f(k) 拉格朗日&#xff08;Lagrange&#xff09;插值公式 搬运 令 L n ( x ) f ( x ) L_n(x)f(x) Ln​(x)f(x) n1 有 由点斜式可以得…

oracle手动锁表

[转载]oracle手动锁表 手工锁表&#xff1a; lock table tbl_t1 in row share mode nowait; --2 lock table tbl_t1 in share update mode nowait; --2 lock table tbl_t1 in row exclusive mode nowait; --3 lock table tbl_t1 in sha…

Oracle数据库锁表解决办法

1.输入查锁语句 SELECT s.sid, s.serial#,b.object_name, s.username, s.schemaname, s.osuser, s.process, s.machine, s.terminal, s.logon_time, l.type FROM v$session s, v$lock l,v$locked_object a,dba_objects b WHERE s.sid l.sid and b.object_id a.object_id and …

Oracle数据库锁表解决

PLSQL不会用,Oracle数据库不了解&#xff0c;哈哈哈,直接闹出了笑话, 由于多次的事务没有提交,导致多个会话没有关闭 造成Oracle数据库表锁死 报 ORA-00054错误 即多个会话没有关闭,Oracle不然你操作了 解决办法 1.查所有被锁的sessionid 用户 哪张表被锁 select l.sessio…

Oracle锁表解决方法

锁表或锁超时相信大家都不陌生&#xff0c;经常发生在DML语句中&#xff0c;产生的原因就是数据库的独占式封锁机制&#xff0c;当执行DML语句时对表或行数据进行锁住&#xff0c;直到事务提交或回滚或者强制结束当前会话。 对于我们的应用系统而言锁表大概率会发生在SQL执行慢…

centos7 升级 gcc 版本

GNU Mirror List 查看动态库版本 strings /usr/lib64/libstdc.so.6 | grep CXXABI查找gcc生成的最新动态库 find / -name "libstdc.so*"一、升级 gcc&#xff1a; 1、查看当前gcc版本 #默认4.8.5 g -v 或者 gcc --version2、下载gcc源码&#xff08;10.2.0&…

环境搭建—3.0 Linaro gcc

一、gcc gcc&#xff0c;GNU Compiler Collection&#xff0c;GNU编译器套件&#xff0c;它最初是专门给GNU操作系统开发的&#xff0c;随着时间推移&#xff0c;现在已经成为了嵌入式领域应用最广泛的c/c编译器工具。不管是单片机开发还是linux开发&#xff0c;都离不开gcc。主…

mac使用gcc编译器

mac自带的编译器是clang编译器而且自带的gcc是映射到clang的之前看到网上需要关闭SIP模式很烦&#xff0c;我试了试关闭了也删除不了gcc&#xff0c;也无法软链接。 后来找到一篇曲线救国的帖子&#xff0c;是在&#xff5e;目录下使用的。 首先下载gcc的最新版本&#xff0c…

win10下安装gcc

win10下安装gcc 一、gcc是什么&#xff1f;1.1、安装gcc 第一次安装,记录一下 一、gcc是什么&#xff1f; GNU编译器套件(GNU Compiler Collection)包括C、C、Objective-C、Fortran、Java、Ada和Go语言的前端&#xff0c;也包括了这些语言的库(如libstdc、libgcj等等)。GCC的初…

gcc

gcc&#xff1a;一个工具集合,包含预处理器,编辑器,汇编器,链接器等组件 说明&#xff1a;当不使用任何选项时,gcc将会生成一个名为a.out的可执行文件 gcc选项 gcc -E 预处理 .igcc -S 编译成汇编代码 .sgcc -c 汇编成目标代码 .ogcc -o 链接成可执行代码 .out/.…

GCC,G++介绍

1.什么是GCC GCC 原名为 GNU C语言编译器&#xff08;GNU C Compiler&#xff09;GCC&#xff08;GNU Compiler Collection&#xff0c;GNU编译器套件&#xff09;是由 GNU 开发的编程语言 译器。GNU 编译器套件包括C、C、Objective-C、Java、Ada 和 Go 语言前 端&#xff0c;…