hihoCoder 1430 : A Boring Problem(一琐繁题)

hihoCoder #1430 : A Boring Problem(一琐繁题)

时间限制:1000ms

单点时限:1000ms

内存限制:256MB


Description - 题目描述

  As a student of the school of electronics engineering and computer science in Peking University, Kyle took the course named Advanced Algebra in his freshman year, which, unluckily, became his nightmare.
  His teacher, Mr. X, has an approximately paranoid requirements in the ability of calculation, from which his students suffer a lot.
  One day, Mr. X got a whim that he wanted to know for a given integer k and a long numeric string S whose length is N, what is the result of   for each i(1 ≤ i ≤ N), where . S[L] means the Lth digit in S, and L starts from 1.
  Mr. X added the problem to the midterm test. Please give a hand to Kyle and tell him the answer mod 1000000007.

作为北大信息科学技术学院的学生,Kyle曾经不知何为噩梦直到大一时候上了一门叫高等代数的课。
他的老师,Mr. X,对计算能力有着丧心病狂的要求。学生们饱受其害。
一天,Mr. X突发奇想,一个整数k与一个长度为N的数字串S,对于每个i(1 ≤ i ≤ N) 式子Σi j=1F(j, i)的结果是什么?这里F(j, i)=(Σi L=j S[L])^k。S[L]表示S的第L个数,L从1开始。
Mr. X把这道题放到了期中考试里。快帮帮Kyle 并告诉他模1000000007后的答案。

CN

Input - 输入

  There are multiple test cases.
  The first line of the input contains an integer T which means the number of test cases.
  The first line of each test case contains two integers, above mentioned N and k.
  The next line is the above mentioned string S. S consists of only digits(‘0 - ‘9‘).

多组测试用例。
输入的第一行为一个整数T,表示测试用例的数量。
每组测试用例的第一行有两个整数,即上述的N与K。
下一行为一个数字串S。S仅包含数字(‘0 - ‘9‘)。

CN

Output - 输出

  For each test case, print a single line representing the result of   for each i(1 ≤ i ≤ N).

对于每个测试用例,输出一行数字表示每个i(1 ≤ i ≤ N)在式子Σi j=1F(j, i)中的结果。

CN

Sample Input - 样例输入

2
5 1
12345
5 1
54321

Sample Output - 样例输出

1 5 14 30 55
5 13 22 30 35

Note - 注意

  T ≤ 5
  N ≤ 50,000, k ≤ 100

题解

  为了防止和后面的说明混淆,字符串中的S[l]用ai代替

  先按题目意思弄出几项,长得有点像01背包。

  这个时候如果按上面的形式做的话,时间复杂度就是O(N*N*Log2K),会爆炸的。

  如果用看,中间的子串就不好表示……而且似乎没法化简(反正本渣没化简出来)。

然后加法不行,用减法?

  使用前N项和(前缀和)就能把每个子串用减法表示出来。

  此处Si表示前i项和,且S0 = 0。

  式子转变如下:

  再把每一项改写成二项展开式:

  合并二项展开式

  用SSi表示前i项S之和,则可以得到通项:

  这个时候时间复杂度就降到O(NK)了。

  注意取模与最后输出,然后就没什么问题了。

代码 C++

 1 #include <cstdio>
 2 #define mod 1000000007
 3 #define mx 50005
 4 #define ll long long
 5 ll c[105][105], s[mx][105], ss[mx][105];
 6 char rd[mx];
 7 int main(){
 8     int t, n, k, i, j;
 9     ll opt, tmp;
10     for (i = 0; i <= 100; ++i){
11         c[i][0] = 1;
12         for (j = 1; j <= i; ++j) c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
13     }
14     for (i = 0; i < mx; ++i) s[i][0] = ss[i][0] = 1;
15
16     for (scanf("%d", &t); t; --t){
17         scanf("%d%d ", &n, &k); gets(rd);
18         for (i = 0; i < n; ++i) s[i + 1][1] = rd[i] - ‘0‘;
19         for (i = 1; i <= n; ++i){
20             s[i][1] = (s[i][1] + s[i - 1][1]) % mod;
21             for (j = 2; j <= k; ++j) s[i][j] = (s[i][j - 1] * s[i][1]) % mod;
22         }
23         for (i = 1; i <= n; ++i){
24             for (j = 0; j <= k; ++j) ss[i][j] = (s[i][j] + ss[i - 1][j]) % mod;
25         }
26
27         for (i = 1; i <= n; ++i){
28             opt = 0;
29             for (j = 0; j <= k; ++j){
30                 tmp = (c[k][j] * s[i][j]) % mod;
31                 if ((k - j) & 1) opt -= (tmp*ss[i - 1][k - j]) % mod;
32                 else  opt += (tmp*ss[i - 1][k - j]) % mod;
33                 opt %= mod;
34             }
35             printf("%lld%c", (opt + mod) % mod, " \n"[i == n]);
36         }
37     }
38     return 0;
39 }
时间: 2024-12-22 10:14:52

hihoCoder 1430 : A Boring Problem(一琐繁题)的相关文章

HDU 5832 A water problem(某水题)

HDU 5832 A water problem(某水题) Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)   Problem Description - 题目描述 Two planets named Haha and Xixi in the universe and they were created with the universe beginning. There is

HDU 4143 A Simple Problem(数论-水题)

A Simple Problem Problem Description For a given positive integer n, please find the smallest positive integer x that we can find an integer y such that y^2 = n +x^2. Input The first line is an integer T, which is the the number of cases. Then T line

Train Problem II 卡特兰裸题(入门题)

Train Problem II  题目大意:给你一个数n,表示有n辆火车,编号从1到n,从远方驶过来,问你有多少种出站的可能. 解题思路:模拟栈的问题而已.  卡特兰问题. 1 import java.math.*; 2 import java.util.*; 3 import java.io.*; 4 5 public class Main 6 { 7 static int MS=101; 8 public static void main(String[] args) 9 { 10 Sca

HDU2101 A + B Problem Too【水题】

A + B Problem Too Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 12745    Accepted Submission(s): 9499 Problem Description This problem is also a A + B problem,but it has a little difference,y

train problem I (栈水题)

杭电1002http://acm.hdu.edu.cn/showproblem.php?pid=1022 Train Problem I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 25276    Accepted Submission(s): 9529 Problem Description As the new term com

HDU1898 Sempr == The Best Problem Solver?【水题】

Sempr == The Best Problem Solver? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 1317    Accepted Submission(s): 865 Problem Description As is known to all, Sempr(Liangjing Wang) had solved mo

hdu 2993 MAX Average Problem(斜率DP入门题)

题目链接:hdu 2993 MAX Average Problem 题意: 给一个长度为 n 的序列,找出长度 >= k 的平均值最大的连续子序列. 题解: 这题是论文的原题,请参照2004集训队论文<周源--浅谈数形结合思想在信息学竞赛中的应用> 这题输入有点大,要加读入优化才能过. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 5

hdu 3549 Flow Problem (最大流入门题)

增广路: 1 /************************************************************* 2 题目: Flow Problem(HDU 3549) 3 链接: http://acm.hdu.edu.cn/showproblem.php?pid=3549 4 题意: 给一个单向图,求从1到n的最大流 5 算法: 最大流之增广路(入门) 6 算法思想: 不断用BFS找通路,没每找一条路,记录这条路的最小流, 7 再给这条路上的所有流量减去这个最小值.

HDU 5427 A problem of sorting 水题

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5427 A problem of sorting Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1447    Accepted Submission(s): 554 Problem Description There are many p