LA 4119 (差分数列 多项式) Always an integer

题意:

给出一个形如(P)/D的多项式,其中P是n的整系数多项式,D为整数。

问是否对于所有的正整数n,该多项式的值都是整数。

分析:

可以用数学归纳法证明,若P(n)是k次多项式,则P(n+1) - P(n)为k-1次多项式。

P是n的一次多项式时,P是一个等差数列,只要验证P(1)和P(2)是D的倍数即可。

P是n的二次多项式时,只要验证第一项为D的倍数,且相邻两项的差值也是D的倍数即可。相邻两项的差值为一次多项式,所以要验证两项,加上前面验证的第一项,所以共验证P(1)、P(2)和P(3)三项。

一般地,要验证k次多项式,只要验证P(1)...P(k+1)即可。

计算多项式的值可以用高中数学课本讲到过的秦九韶算法。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <string>
 4 #include <cstring>
 5 #include <cstdlib>
 6 using namespace std;
 7
 8 const int maxn = 100 + 10;
 9 int a[maxn], p;//a[i]表示n^i对应的系数,p为最高系数
10
11 void parse_polynomial(string s)
12 {
13     int i = 0, len = s.size();
14     while(i < len)
15     {
16         int sign = 1;
17         if(s[i] == ‘+‘) i++;
18         if(s[i] == ‘-‘) { i++; sign = -1; }
19         int v = 0;//系数
20         while(i < len && isdigit(s[i])) v = v * 10 + s[i++] - ‘0‘;
21         v *= sign;
22         if(i == len) a[0] = v;//常数项
23         else
24         {
25             if(v == 0) v = sign;
26             int u = 1;//没有指数
27             if(s[++i] == ‘^‘)//有指数
28             {
29                 u = 0;
30                 i++;
31                 while(isdigit(s[i])) u = u * 10 + s[i++] - ‘0‘;
32             }
33             a[u] = v;
34             if(u > p) p = u;
35         }
36     }
37 }
38
39 int mod(int x, int MOD)
40 {
41     int ans = 0;
42     for(int i = p; i >= 0; i--)
43     {
44         ans = (long long) ans * x % MOD;//注意不要溢出
45         ans = ((long long) ans + a[i]) % MOD;
46     }
47     return ans;
48 }
49
50 bool check(string& expr)
51 {
52     int p = expr.find(‘/‘);
53     parse_polynomial(expr.substr(1, p-2));
54     int D = atoi(expr.substr(p+1).c_str());
55     for(int i = 1; i <= p+1; i++)
56         if(mod(i, D) != 0) return false;
57     return true;
58 }
59
60 int main()
61 {
62     //freopen("in.txt", "r", stdin);
63
64     int kase = 1;
65     string expr;
66     while(cin >> expr)
67     {
68         if(expr[0] == ‘.‘) break;
69         memset(a, 0, sizeof(a));
70         p = 0;
71         printf("Case %d: %s\n", kase++, check(expr) ? "Always an integer" : "Not always an integer");
72     }
73
74     return 0;
75 }

代码君

时间: 2024-10-08 11:13:00

LA 4119 (差分数列 多项式) Always an integer的相关文章

hdu4970 Killing Monsters (差分数列)

2014多校9 1011 http://acm.hdu.edu.cn/showproblem.php?pid=4970 Killing Monsters Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 331    Accepted Submission(s): 198 Problem Description Kingdom Rush

【差分数列】tyvj2042线段问题

线段问题 描述 Description 有N条线段,已知每条线段的起点和终点(50000以内),然后有M个询问,每次询问一个点(50000以内),求这个点在多少条线段上出现过? 输入格式 InputFormat 第一行N线段条数接下来N行,每行两个数,线段的起点和终点第N+2行一个数M询问个数接下来M行,每行一个点 输出格式 OutputFormat 对于每个询问,求答案 样例输入 SampleInput 3 2 5 4 6 0 7 4 2 4 7 6 样例输出 SampleOutput 2 3

差分数列+树状数组

差分数列+树状数组:可以把树状数组的“单点修改,区间查询”-->改变为“区间修改和单点查询” 例题: codevs 1081 线段树练习 2 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作 1:给区间[a,b]的所有数都增加X 2:询问第i个数是什么? 输入描述 Input Description 第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,表示操作的个数. 接下来Q行每行若干个整数

BZOJ1635 [Usaco2007 Jan]Tallest Cow 最高的牛 数列差分

Description FJ's N (1 <= N <= 10,000) cows conveniently indexed 1..N are standing in a line. Each cow has a positive integer height (which is a bit of secret). You are told only the height H (1 <= H <= 1,000,000) of the tallest cow along with

uvalive 4119 Always an Interger

差分数列+字符串处理 题意:是让你判断一个整系数多项式的值是否一直都能被一个所给的正整数所整除. 通过对差分数列的不断求导,我们可以发现,对于任意多项式P,我们只需要判断n从1到k+1是否满足就行了,其中,k为多项式P中的最高次数. 可以先了解一下差分数列. 1 #include <iostream> 2 #include <cstdio> 3 #include<cstdlib> 4 #include<cctype> 5 #include<string

bzoj千题计划293:bzoj3142: [Hnoi2013]数列

http://www.lydsy.com/JudgeOnline/problem.php?id=3142 如果已知数列的差分数列a[1]~a[k-1] 那么这种差分方式对答案的贡献为 N-Σ a[i],i∈[1,k-1] 差分数列一共有多少种? M^(k-1) 种 所以ans=Σ  (N-Σa[i]) = M^(k-1) * N - Σ Σ a[i] = M^(k-1) *N-(k-1)*M^(k-1) /M * (M+1)*M/2 后面是因为一共 M个数 出现(k-1)*M^(k-1) 次,每

2019上海icpc网络赛B. Light bulbs(思维+差分)

题目传送门 题意 T组案例,每组案例:n个灯泡(from 0 to n-1),m次操作,每次操作把区间[L,R]内的灯泡翻转(开变关,关变开),问m次操作之后有多少灯泡是亮着的.(时间限制:1000ms  内存限制:8192K) 题解 这道题不仅卡时间,更是卡内存,所以用线段树会爆内存 正解: 该题可以转换为经典的差分问题:每次操作对[L,R]的所有数进行+1操作,求最后有多少个奇数.(设该数组为a[n],每次操作a[L]+1,a[R+1]-1,求前缀和sum[i]=sum[i-1]+a[i]即

差分总结

最近在蓝书上看了差分,发现自己并没有真正的理解,CSP前的考试有一道裸的差分题我都是用线段树写的,现在做了几道题,感觉对查分的理解更深了 给定一个数列\(a[i]\),查分数列\(b[i]=a[i]-a[i-1]\) for(int i=1; i<=n; i++) { scanf("%d",&a[i]); if(i!=1) b[i]=a[i]-a[i-1]; } 如果数列\(a[i]\)是 1 5 2 7 9 3 那么数列\(b[i]\)就是 0 4 -3 5 2 -6

清北学堂学习总结 day1 数据结构 练习

1.二叉搜索树 STL set直接做就可以了 2.树状数组+差分数列: codevs 1081 线段树练习 2 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作 1:给区间[a,b]的所有数都增加X 2:询问第i个数是什么? 输入描述 Input Description 第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,表示操作的个数. 接下来Q行每行若干个整数.如果第一个数是1,后接3个正