Ural 1309 Dispute (递推)

题意:

给你一个数列:

f(0) = 0

f(n) = g(n,f(n-1))

g(x,y) = ((y-1)*x^5+x^3-xy+3x+7y)%9973

让你求f(n)  n <= 1e8

思路:

令m = 9973

容易观察g(x,y) = g(x%m,y)

f(x+m) = g( (x+m) %m , f(x+m-1))........

可以得到 f(x+m) = (A*f(x)+B)%m

f(x+2m) = (A*f(x+m)+B)%m

,.....

令x+km = n

先求出f(x) 在求出A,B然后算出f(n)

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int m = 9973;
int A,B;
int n;
int x,cnt;
int getX5(int x){
    int ret = 1;
    for(int i = 1; i <= 5; i++) {
        ret = (x*ret)%m;
    }
    return ret;
}
int getX3(int x) {
    int ret = 1;
    for(int i = 1; i <= 3; i++) {
        ret = (ret*x)%m;
    }
    return ret;
}
int getPos(int x) {
    return (x%m+m)%m;
}
int func(int n) {
    if(n==0) return 0;
    return getPos((getPos(getX5(n)-n+7)*func(n-1))%m+getPos((-getX5(n)+getX3(n)+3*n)));

}
void solve() {
    A = 1;
    B = 0;
    int ret = func(x);
    for(int i = x+m; i >= x+1; i--) {
        int k = i%m;
        B = (B+A*getPos((-getX5(k)+getX3(k)+3*k)))%m;
        A = (A*getPos(getX5(k)-k+7))%m;
    }
    for(int i = 1; i <= cnt; i++) {
        ret = (A*ret+B)%m;
    }
    printf("%d\n",ret);

}
int main() {
    while(~scanf("%d",&n)) {
        x = n%m;
        cnt = n/m;
        solve();

    }
    return 0;
}
时间: 2024-10-25 14:57:59

Ural 1309 Dispute (递推)的相关文章

递推DP URAL 1031 Railway Tickets

题目传送门 1 /* 2 简单递推DP:读题烦!在区间内的都更新一遍,dp[]初始化INF 3 注意:s1与s2大小不一定,坑! 4 详细解释:http://blog.csdn.net/kk303/article/details/6847948 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cstring> 10 #include <s

递推DP URAL 1119 Metro

题目传送门 1 /* 2 题意:已知起点(1,1),终点(n,m):从一个点水平或垂直走到相邻的点距离+1,还有k个抄近道的对角线+sqrt (2.0): 3 递推DP:仿照JayYe,处理的很巧妙,学习:) 4 好像还要滚动数组,不会,以后再补 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <algorithm> 9 #include <cmath> 10 #include <cs

递推DP URAL 1353 Milliard Vasya&#39;s Function

题目传送门 1 /* 2 题意:1~1e9的数字里,各个位数数字相加和为s的个数 3 递推DP:dp[i][j] 表示i位数字,当前数字和为j的个数 4 状态转移方程:dp[i][j] += dp[i-1][j-k],为了不出现负数 5 改为:dp[i][j+k] += dp[i-1][j] 6 */ 7 #include <cstdio> 8 #include <cstring> 9 #include <cmath> 10 #include <algorithm

递推DP URAL 1260 Nudnik Photographer

题目传送门 1 /* 2 递推DP: dp[i] 表示放i的方案数,最后累加前n-2的数字的方案数 3 */ 4 #include <cstdio> 5 #include <algorithm> 6 #include <cmath> 7 #include <cstring> 8 using namespace std; 9 10 const int MAXN = 1e4 + 10; 11 const int INF = 0x3f3f3f3f; 12 int

递推DP URAL 1017 Staircases

题目传送门 1 /* 2 题意:给n块砖头,问能组成多少个楼梯,楼梯至少两层,且每层至少一块砖头,层与层之间数目不能相等! 3 递推DP:dp[i][j] 表示总共i块砖头,最后一列的砖头数是j块的方案数 4 状态转移方程:dp[i][j] += dp[i-j][k] 表示最后一列是j,那么上一个状态是少了最后一列 5 总共i-j块砖头,倒数第二列是k块砖头.k<j, j<=i 6 最后累加dp[n][i], i<n因为最少要两层 7 dp[0][0] = 1; 8 还有更简单的做法,没

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往

hdu 1267 递推

下沙的沙子有几粒? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4326    Accepted Submission(s): 2268 Problem Description 2005年11月份,我们学校参加了ACM/ICPC 亚洲赛区成都站的比赛,在这里,我们获得了历史性的突破,尽管只是一枚铜牌,但获奖那一刻的激动,也许将永远铭刻

hdu 2067(递推或卡特兰数【待补充】)

//解法一:递推#include<iostream> using namespace std; long long d[36][36]; int main() { for(int i=1;i<=35;i++) { d[0][i]=1; } for(int i=1;i<=35;i++) for(int j=i;j<=35;j++) { if(i==j) d[i][j]=d[i-1][j]; else d[i][j]=d[i-1][j]+d[i][j-1]; } int n; i

NPU 2015年陕西省程序设计竞赛网络预赛(正式赛)F题 和谐的比赛(递推 ||卡特兰数(转化成01字符串))

Description 今天西工大举办了一场比赛总共有m+n人,但是有m人比较懒没带电脑,另外的n个人带了电脑.不幸的是,今天机房的电脑全坏了只能用带的电脑,一台电脑最多两人公用,确保n>=m.但是大家来的时间不同,随机次序来机房,带电脑的人直接准备比赛而没带电脑的人需要向带电脑并还没和别人公用的人求助(当然会答应).但是,如果不存在带电脑并还没和别人公用的人,那他就要等了,等是很让人头疼的,这就不和谐了,当然假如没有这样的情况发生比赛是很和谐的. Input 输入多组数据,每组数据只有一行m(