luogu1771 方程的解
题目大意
对于不定方程a1+a2+…+ak-1+ak=g(x),其中k≥2且k∈N,x是正整数,g(x)=x^x mod 1000(即x^x除以1000的余数),x,k是给定的数。我们要求的是这个不定方程的正整数解组数。
DP(暴力)解法
定义F(p, rest)为第p个数,p及p后面的数的和为rest的解的数量,递归式为:F(p, rest)=if(rest==0)0 else if (p == k) rest else sum foreach curVal(0<curVal<=rest) F(p, rest - curVal)。
不用高精度,本方法能得40分。
注意
curVal<=rest就可以了,反正如果curVal大了以后也能返回0,不要擅自进一步缩小curVal的范围。
#include <cstdio>
#include <cstring>
using namespace std; #define ll long long
#define _NDEBUG const int MAX_K = 110, MAX_X = 1010, P = 1000;
ll F[MAX_K][MAX_X];
ll K, X; ll Mult(ll a, ll b, ll p)
{
ll ans = 0;
while (b)
{
if (b & 1)
ans = (ans + a) % p;
a = (a + a) % p;
b >>= 1;
}
return ans;
} ll Power(int a, int n, int p)
{
ll ans = 1;
while (n)
{
if (n & 1)
ans = Mult(ans, a, p);
a = Mult(a, a, p);
n >>= 1;
}
return ans;
} ll DP(int p, ll rest)
{
if (F[p][rest] != -1)
return F[p][rest];
if (rest == 0)
return F[p][rest] = 0;
if (p == K)
return F[p][rest] = 1;
F[p][rest] = 0;
for (int i = 1; i <= rest; i++)
F[p][rest] += DP(p + 1, rest - i);
return F[p][rest];
} int main()
{
scanf("%lld%lld", &K, &X);
memset(F, -1, sizeof(F));
printf("%lld\n", DP(1, Power(X, X, P)));
return 0;
}
组合数学解法
把x^x%1000看作一个线段,a1,a2...看作一个个隔板划分出的区域,这就是组合数学中的隔板模型,最终结果为C(k,x^x%1000)
注意
- 求组合数的模板就这样定死了,不要改。
- 高精度里最好把=运算符写上。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; #define ll long long const int MAX_K = 110, MAX_X = 1010, P = 1000, BASE = 10000, CARRY = 4, MAX_LEN = 1010;
ll K, X; ll Mult(ll a, ll b, ll p)
{
ll ans = 0;
while (b)
{
if (b & 1)
ans = (ans + a) % p;
a = (a + a) % p;
b >>= 1;
}
return ans;
} ll Power(int a, int n, int p)
{
ll ans = 1;
while (n)
{
if (n & 1)
ans = Mult(ans, a, p);
a = Mult(a, a, p);
n >>= 1;
}
return ans;
} struct BigInt
{
private:
int A[MAX_LEN];
int Len; public:
void Clear()
{
memset(A, 0, sizeof(A));
Len = 0;
} void Set(int x)
{
Clear();
while (x)
{
A[Len++] = x%BASE;
x /= BASE;
}
while (A[Len] == 0 && Len > 0)
Len--;
} BigInt() { Clear(); } BigInt operator = (const int x)
{
Set(x);
return *this;
} BigInt operator = (const BigInt &a)
{
memcpy(A, a.A, sizeof(A));
Len = a.Len;
return *this;
} void Print()
{
printf("%d", A[Len]);
for (int i = Len - 1; i >= 0; i--)
printf("%0*d", CARRY, A[i]);
printf("\n");
} BigInt operator += (const BigInt &a)
{
Len = max(Len, a.Len);
for (int i = 0; i <= Len; i++)
{
A[i] += a.A[i];
A[i + 1] += A[i] / BASE;
A[i] %= BASE;
}
if (A[Len + 1])
Len++;
return *this;
} BigInt operator + (const BigInt &a)
{
BigInt Num = *this;
return Num += a;
}
}; BigInt Comb(int r, int n)
{
static BigInt C[MAX_K];
C[0] = 1;
for (int i = 1; i <= n; i++)
{
for (int j = min(r, i); j > 0; j--)
{
if (i == j)
C[j] = 1;
else
C[j] = C[j - 1] + C[j];
}
}
return C[r];
} int main()
{
scanf("%lld%lld", &K, &X);
Comb(K - 1, Power(X,X,P) - 1).Print();
return 0;
}
luogu1771 方程的解的更多相关文章
- vijosP1371 方程的解
vijosP1371 方程的解 链接:https://vijos.org/p/1371 [思路] 组合公式+快速幂+高精单精. 求x^x %1000:因为x最大为2^31-1所以用快速幂在O(logx ...
- 方程的解_NOI导刊2010提高
方程的解 给定x,求\(a_1+a_2+...+a_k=x^x\ mod\ 1000\)的正整数解解的组数,对于100%的数据,k≤100,x≤2^31-1. 解 显然x是可以快速幂得到答案的,而该问 ...
- P1771 方程的解_NOI导刊2010提高(01)
P1771 方程的解_NOI导刊2010提高(01) 按题意用快速幂把$g(x)$求出来 发现这不就是个组合数入门题吗! $k$个人分$g(x)$个苹果,每人最少分$1$个,有几种方法? 根据插板法, ...
- 【Java例题】4.4使用牛顿迭代法求方程的解
4. 使用牛顿迭代法求方程的解:x^3-2x-5=0区间为[2,3]这里的"^"表示乘方. package chapter4; public class demo4 { publi ...
- 模拟7题解 T1方程的解
方程的解 [扩展欧几里德] 首先进行特判,两个小时基本想到了,除了a!=0,b==0,a*c<0这种情况 其次就是一般情况: 首先exgcd求出ax+by=GCD(a,b)的一组任意解 然后两边 ...
- 洛谷P1771 方程的解
P1771 方程的解 都知道这个题可以用隔板法做 把这个\(g(x)\)想象为.....\(g(x)\)个苹果? 因为解是正整数,所以给这些"苹果"分组的时候每组最少有一个 然后我 ...
- codevs3732==洛谷 解方程P2312 解方程
P2312 解方程 195通过 1.6K提交 题目提供者该用户不存在 标签数论(数学相关)高精2014NOIp提高组 难度提高+/省选- 提交该题 讨论 题解 记录 题目描述 已知多项式方程: a ...
- C++ 二分法求解方程的解
二分法是一种求解方程近似根的方法.对于一个函数 f(x)f(x),使用二分法求 f(x)f(x) 近似解的时候,我们先设定一个迭代区间(在这个题目上,我们之后给出了的两个初值决定的区间 [-20,20 ...
- [CSP-S模拟测试]:方程的解(小学奥数)
题目描述 给出一个二元一次方程$ax+by=c$,其中$x$.$y$是未知数,求它的正整数解的数量. 输入格式 第一行一个整数$T$,表示有$T$组数据.接下来$T$行,每行$3$个整数$a$.$b$ ...
随机推荐
- C# 多线程系列(一)
线程是怎样工作的 1.多线程由一个线程调度器来进行内部管理,一个功能是CLR常常委托给操做系统. 一个线程调度器确保所有激活的线程在执行期间被合适的分配,等待或者阻塞的线程(比如,一个独占锁或者等待用 ...
- 01--Java IO基础
一.java.io包概览 Java IO包主要可以分为如下4类: 基于字节操作的I/O接口:InputStream和OutputStream. 基于字符操作的I/O接口:Writer和Reader 基 ...
- js 字符串 处理方法
charAt() 返回指定索引位置的字符 charCodeAt() 返回指定索引位置字符的 Unicode 值 concat() 连接两个或多个字符串,返回连接后的字符串 fromCharCode() ...
- SQL Server存储过程作业(二)
阶段1:练习——统计某类型客房的入住客人人数 需求说明 使用存储过程统计在指定类型的客房入住客人的总人数 提示: 存储过程的输入参数是指定的客房类型名称 USE Hotel GO --阶段1:查询入住 ...
- 4、scala数组
1.Array 2.ArrayBuffer 3.遍历Array和ArrayBuffer 4.数组常见操作 1. Array Scala中,array代表的含义与java类似,也是长度不可改变的数组. ...
- C#遍历/反射 属性/字段
public static string SortParam<T>(T t) { string tStr = string.Empty; if (t == null) { return s ...
- ASP.NET 页面验证cookie
using System; using System.Collections.Generic; using System.Linq; using System.Web; /// <summary ...
- [luogu4251 SCOI2015] 小凸玩矩阵 (二分图最大匹配)
传送门 Description Input Output 输出包含一行,为选出的 n 个数中第 k 大数的最小值. Sample Input 输入样例1: 2 3 1 1 2 4 2 4 1 输入样例 ...
- [jzoj 5782]【NOIP提高A组模拟2018.8.8】 城市猎人 (并查集按秩合并+复杂度分析)
传送门 Description 有n个城市,标号为1到n,修建道路花费m天,第i天时,若gcd(a,b)=m-i+1,则标号为a的城市和标号为b的城市会建好一条直接相连的道路,有多次询问,每次询问某两 ...
- 在eclipse中运行maven命令没有反应,console也不打印信息
eclipse的maven项目中,在run as 执行maven命令的时候发现毫无反应,console也不打印信息,原因是因为没有传参数,解决办法如下:①打开eclipse的window菜单: ②接 ...