2017 9 27 模拟赛T1

题意简述:

求1—n中所有数的k次方的和,答案对1234567891取模。

样例输入格式:

一行,两个整数n,k

样例输出格式:

一个整数,即所求的和。

数据范围:n<10^9,k<100

这道题n非常大,即使是O(n)的算法也不能承受,但是此题的k却非常小,这也就提醒由k入手。

首先预处理前k+1个数的k次方的和,如果n<=k+1的话其实就可以直接输出a[0][n]了,不过我觉得出题人不会出这样的数据。

为什么是k+1个数呢?这是为了能处理一些差分的问题。

然后不断地计算每一行的差分,比如这样:

3 2

0 1 5 14

0 1 4 9

0 0 3 5

0 0 0 2

对于每一个a[i][i],其中存储的便是每一个i^k-(i-1)^k-(i-2)^k...-2^k-1^k的值。

即使没有学过导数,也应该能想象,在k>1的情况下,y=x^k这个函数的增长是越来越快的。

假设x1<x2,那么必有 x2^k - (x2-x)^k  > x1^k - (x1-x)^k (k>0,x为正整数且x<x1)

然后就能发现,在n个数中任选i个数,所选的数中,最大的数与最小的数之间至少会产生a[i][i]的差值。

组数是一个组合的关系,也就是C(n,i),乘上a[i][i]后加进和中即可。

计算出所有差值并将其累加,就能得到最终结果。

代码来自标程。

#include<cstdio>
long long n,k,p=1234567891,tmp=1;
long long a[105][105],ans;
long long pow(long long x,long long y)
{
    long long re=1;
    for(;y;y>>=1)
    {
        if(y&1) re=re*x%p;
        x=x*x%p;
    }
    return re;
}
int main()
{
    scanf("%lld%lld",&n,&k);
    for(int i=1;i<=k+1;i++) a[0][i]=(a[0][i-1]+pow(i,k))%p;
    for(int i=1;i<=k+1;i++)
    {
        for(int j=i;j<=k+1;j++)    a[i][j]=(a[i-1][j]-a[i-1][j-1]+p)%p;
    }
    for(int i=0;i<=k+1;i++)
    {
        ans=(ans+a[i][i]*tmp)%p;
        tmp=tmp*(n-i)%p*pow(i+1,p-2)%p;
    }
    printf("%lld",ans);
    return 0;
}
时间: 2024-08-26 18:07:45

2017 9 27 模拟赛T1的相关文章

2017/9/3模拟赛T1

题解:这题是一道判断题,分5种情况讨论,以下为了方便以ABC为例 ①若只有A,答案为A ②若A.B.C都有,答案为ABC ③若只有AB,答案为C ④若AAB式,答案为BC ⑤若只有A.B且AB均大等于2,答案为ABC 代码如下: 1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 int n,cnt[3],cur; 5 char a[205]; 6 bool pd(){ 7 for(int i=0;i&l

2017 11 6模拟赛T1

作为一个毒瘤出题人(wzy:我不是毒瘤出题人,这些题明明很水的),wzy的题干十分复杂,但是把题意简化之后,相当简单粗暴... 求首项为1,等比为m,项数为t的等比数列的和,答案对k取模 不保证m与k互质 如果m与k互质的话,用等比数列的求和公式在求个逆元就能解决了,但是本题显然不能,于是必须考虑不含有除法的算法 于是就有了分治求等比数列和的办法. 设s(x)为等比数列的第n项 由等比数列的性质得到s(y)=s(x)*m^(y-x) (y>x) 将一个长度为2r的等比数列拆分成登场的两部分,对应

2017 9 27 模拟赛 T2

原题题意:给出一个集合S,现满足以下关系: 实际题意:求32的n次方(这...)

11.27 模拟赛

并没有人做的模拟赛... 出题人hx,,, T1:就是上一道矩阵乘法 数学题 T2: 一个数列中 一个区间满足,存在一个k(L <= k <= R),并且对于任意的i (L <= i <= R),ai都能被ak整除 这样的一个特殊区间 [L, R]价值为R - L 想知道序列中所有特殊区间的最大价值是多少,而有多少个这样的区间呢 这些区间又分别是哪些呢 输出每个区间的L 思路: 用两个ST表分别求一段区间的gcd和最小值 然后可以二分答案 check的时候枚举左端点,判断在这段区间

20180610模拟赛T1——脱离地牢

Description 在一个神秘的国度里,年轻的王子Paris与美丽的公主Helen在一起过着幸福的生活.他们都随身带有一块带磁性的阴阳魔法石,身居地狱的魔王Satan早就想着得到这两块石头了,只要把它们溶化,Satan就能吸收其精华大增自己的魔力.于是有一天他趁二人不留意,把他们带到了自己的地牢,分别困在了不同的地方.然后Satan念起了咒语,准备炼狱,界时二人都将葬身于这地牢里. 危险!Paris与Helen都知道了Satan的意图,他们要怎样才能打败魔王,脱离地牢呢?Paris想起了父王

10.27 模拟赛

这一次终极被吊打 甚至没进前十 T2 最后改错 T3 没写正解 T1 elim 题目大意: n 行 m 列的游戏棋盘,一行或一列上有连续 三个或更多的相同颜色的棋子时,这些棋子都被消除 当有多处可以被消除时,这些地方的棋子将同时被消除 求消除后的棋盘 思路: sb模拟 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cm

2017 7.22 模拟赛

最水的一次模拟赛.. 点击查看题目 T1 求最后K位  那前面的数是没有比要求的 , 我们就把 10k 作为模数 ,对答案进行取模 就好了  #include <ctype.h> #include <cstdio> #define N 100005 typedef long long LL; void read(LL &x) { x=0;bool f=0; register char ch=getchar(); for(;!isdigit(ch);ch=getchar())

2017 6 11模拟赛

盘子序列 [题目描述] 有 n 个盘子.盘子被生产出来后,被按照某种顺序摞在一起.初始盘堆中如果一 个盘子比所有它上面的盘子都大,那么它是安全的,否则它是危险的.称初始盘堆为 A,另外有一个开始为空的盘堆 B.为了掩盖失误,生产商会对盘子序列做一些“处 理” ,每次进行以下操作中的一个:(1)将 A 最上面的盘子放到 B 最上面:(2)将 B 最上 面的盘子给你. 在得到所有n个盘子之后, 你需要判断初始盘堆里是否有危险的盘子. [输入格式] 输入文件包含多组数据(不超过 10 组) 每组数据的

2017/9/29模拟赛

T1.多米诺骨牌(card)小 Z 最近买了很多很多的多米诺骨牌,他选出了其中的一些排成了一排,并且准备从右到左碰倒这些骨牌.每个骨牌有一个坐标 xi(>=1)和一个大小 yi(>=1),倒下时将会碰倒坐标区间位于[xi-yi,xi)内的所有骨牌.当然没有两个骨牌有相同的坐标, 并且小 Z 规定坐标大的更靠右.但是他发现他买的骨牌太巨了,所以在倒下的时候会将所有碰倒的骨牌破坏掉,被破坏掉的骨牌就无法使用了,并且不会倒下.得知这个消息的小 Z 十分惊讶,他想知道如果还按刚才这种方法从右到左碰倒所