1. 程式人生 > >差分序列(poj 2914 Angry Teacher & poj 2515 Birthday Cake)

差分序列(poj 2914 Angry Teacher & poj 2515 Birthday Cake)


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();
	}
}