差分序列(poj 2914 Angry Teacher & poj 2515 Birthday Cake)
阿新 • • 發佈:2019-01-01
poj 2515 Birthday Cake
題意:給出m和n,求Sigma(i^m) 0<i<n
解法:最裸的差分序列,根據性質3,只需求得第0條對角線的n+1個值即可。
poj 2094 Angry Teacherimport 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(); } }
題意:給出一個多項式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(); } }