poj 2515 Birthday Cake
题意:给出m和n,求Sigma(i^m) 0<i<n
解法:最裸的差分序列,根据性质3,只需求得第0条对角线的n+1个值即可。
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.Scanner;
public class Main{
Scanner scan = new Scanner(System.in);
BigInteger c[]=new BigInteger[110];
BigInteger h[][] = new BigInteger[110][110];
void getc(BigInteger n, int m) {
c[1] = n;
for (int i = 2; i <= m+1; i++)
c[i] = c[i - 1].multiply(n.subtract(BigInteger.valueOf(i - 1)))
.divide(BigInteger.valueOf(i));
}
PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
void run() {
int cas=scan.nextInt();
while(cas-->0){
BigInteger n =scan.nextBigInteger().add(BigInteger.ONE);
int m = scan.nextInt();
for (int i = 0; i <= m; i++)
h[0][i] = BigInteger.valueOf(i).pow(m);
for (int i = 1; i <= m; i++)
for (int j = 0; j <= m - i; j++)
h[i][j] = h[i - 1][j + 1].subtract(h[i - 1][j]);
BigInteger ans = BigInteger.ZERO;
getc(n, m);
for (int i = 0; i <= m; i++)
ans=ans.add(h[i][0].multiply(c[i+1]));
out.println(ans);
out.flush();
}
}
public static void main(String[] args) {
new Main().run();
}
}
poj 2094 Angry Teacher
题意:给出一个多项式p(x)=a[n]*x^n+...+a[1]*x+a[0],并给初始x值L,和数m,k,求出从x=L,L+1,...L+k-1的 p(x)的最后m个数字的平方和,即若p(x)=34,则输出3*3+4*4=25,x的值从L到L+k-1.且初始值l和多项式的常数 a[i]可能很大,最大到10^1000.多项式最高次最大为10
解法:目测高精暴力应该可以过,但是此题卡的紧,因此考虑用差分序列做对于前n项暴力求出并构造出差分表,对于后n-k项,利用差分表最后一行是一个常数的性质,自底向上递推一次得到第n+1项第n+2项、、、每次只需记录每行最后一个元素的变化即可。
import java.math.BigInteger;
import java.util.Scanner;
public class AngryTeacher {
BigInteger h[][] = new BigInteger[15][15];
BigInteger a[] = new BigInteger[15], st, mod;
int n, m, k;
Scanner scan = new Scanner(System.in);
void build() {
for (int i = 0; i < Math.min(n + 1, k); i++) {
BigInteger res = a[0];
for (int j = 1; j <= n; ++j) {
res = res.multiply(st);
res = res.add(a[j]);
}
res = res.mod(mod);
st=st.add(BigInteger.ONE);
h[0][i] = res;
System.out.println(cal(res.toString()));
}
if(k<=n+1) return;
for (int i = 1; i <= n; i++)
for (int j = 0; j <= n-i; j++)
h[i][j] = h[i - 1][j + 1].subtract(h[i - 1][j]);
}
BigInteger pre[] = new BigInteger[15];
void work() {
for (int j = 0; j <= n; j++)
pre[j] = h[j][n-j];
for (int i = n + 1; i < k; i++) {
BigInteger res=h[n][0];
for(int j=n-1;j>=0;j--){
res=pre[j].add(res);
res=res.mod(mod);
pre[j]=res;
}
System.out.println(cal(res.toString()));
}
}
int cal(String s) {
int len = Math.min(s.length(), m);
int ans = 0, temp;
for (int i = 0; i < len; i++) {
temp = s.charAt(i) - '0';
ans += temp * temp;
}
return ans;
}
void init() {
n = scan.nextInt();
st = scan.nextBigInteger();
k = scan.nextInt();
m = scan.nextInt();
mod = BigInteger.TEN.pow(m);
for (int i =0;i<=n; i++)
a[i] = scan.nextBigInteger();
}
void run(){
init();
build();
work();
}
public static void main(String[] args) {
new AngryTeacher().run();
}
}