BZOJ1712: [Usaco2007 China]Summing Sums 加密

n<=50000个数做t<=1?????????反正不爆int次操作,每次把一个数组中每一个数变成当前,当前,当前数组的其他数的和,就是然后求最后每个Ai

每个数做的操作是一样的而且每个数加上的其他数的系数都是一样的,实验可得最后每个数都会变成:

至于x,y用矩阵算,base矩阵如下:

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<stdlib.h>
 4 #include<algorithm>
 5 //#include<iostream>
 6 using namespace std;
 7 
 8 #define LL long long
 9 typedef LL mat[4][4];
10 mat start,a,t;
11 const int mod=98765431;
12 void init(mat &a)
13 {
14     memset(a,0,sizeof(a));
15     a[1][1]=a[2][2]=1;
16 }
17 void copy(mat &a,mat b) {memcpy(a,b,sizeof(mat));}
18 void mul(mat a,mat b,mat &ans)
19 {
20     mat t;memset(t,0,sizeof(t));
21     for (int i=1;i<=2;i++)
22         for (int j=1;j<=2;j++)
23             for (int k=1;k<=2;k++)
24                 t[i][j]=(t[i][j]+a[i][k]*b[k][j]%mod)%mod;
25     copy(ans,t);
26 }
27 void pow(mat a,LL b,mat &ans)
28 {
29     mat t,tmp;init(t);copy(tmp,a);
30     while (b)
31     {
32         if (b&1) mul(t,tmp,t);
33         mul(tmp,tmp,tmp);
34         b>>=1;
35     }
36     copy(ans,t);
37 }
38 int n,K;
39 #define maxn 50011
40 LL num[maxn],sum;
41 int main()
42 {
43     scanf("%d%d",&n,&K);sum=0;
44     for (int i=1;i<=n;i++) scanf("%lld",&num[i]),sum+=num[i],sum-=sum>mod?mod:0;
45     start[1][1]=1;start[2][1]=0;
46     a[1][1]=0;a[1][2]=n-1;a[2][1]=1;a[2][2]=n-2;
47     pow(a,K,t);mul(t,start,t);
48     for (int i=1;i<=n;i++) printf("%lld\n",((t[1][1]*num[i]%mod+t[2][1]*(sum-num[i])%mod)%mod+mod)%mod);
49     return 0;
50 }
View Code

 

posted @ 2017-09-08 14:00  Blue233333  阅读(138)  评论(0编辑  收藏  举报