51nod1773 A国的贸易
基準時間限制:2秒 空間限制:524288KB 分值:40
A國是一個神奇的國家。
這個國家有2n個城市,每個城市都有一個獨一無二的編號 ,編號范圍為0~2n-1。
A國的神奇體現在,他們有著神奇的貿易規則。
當兩個城市u,v的編號滿足calc(u,v)=1的時候,這兩個城市才可以進行貿易(即有一條邊相連)。
而calc(u,v)定義為u,v按位異或的結果的二進制表示中數字1的個數。
ex:calc(1,2)=2 ——> 01 xor 10 = 11
calc(100,101)=1 ——> 0110,0100 xor 0110,0101 = 1
calc(233,233)=0 ——> 1110,1001 xor1110,1001 = 0
每個城市開始時都有不同的貨物存儲量。
而貿易的規則是:
每過一天,可以交易的城市之間就會交易一次。
在每次交易中,當前城市u中的每個貨物都將使所有與當前城市u有貿易關系的城市貨物量 +1 。
請問 t 天后,每個城市會有多少貨物。
答案可能會很大,所以請對1e9+7取模。
Input
第一行兩個正整數n,t,意義如題。 第二行2^n個非負整數,第i個數表示編號為i-1的城市的初始貨物存儲量。 n<=20t<=10^9
Output
輸出一行2^n個非負整數。 第i個數表示過了t天后,編號為i-1的城市上的貨物數量對1e9+7取模的結果。
Input示例
樣例1: 32 12345678 樣例2: 11 01
Output示例
樣例1: 5862667074788286 樣例2: 11
動態規劃 FWT
根據題意一天到下一天的轉移有兩種:
1、從f[x]轉移到f[x](累加自身)
2、從f[x]轉移到f[x Xor 2^i]
轉化一下視角,從上一天到這天的轉移有兩種:
1、從f[x Xor 2^0]到f[x]
2、從f[x Xor 2^i]到f[x]
顯然,我們構造一個數組B,使得B只有0和2的冪次位為1,其他位為0,和原數組做異或卷積就能得到一次轉移的結果。
加個快速冪就可以了。
需要輸出優化。
博主不知道是有多困(chun),才能做到FWT的時候只變換原數組不變換B數組就直接乘,還如同星際選手一般地反復在其他地方找bug……
1 #include<iostream>
2 #include<algorithm>
3 #include<cstring>
4 #include<cstdio>
5 #include<cmath>
6 #define LL long long
7 using namespace std;
8 const int mod=1e9+7;
9 const int inv2=500000004;
10 const int mxn=2330010;
11 int read(){
12 int x=0,f=1;char ch=getchar();
13 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
14 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
15 return x*f;
16 }
17 void write(int x){
18 if(x>9)write(x/10);
19 putchar('0'+x%10);
20 return;
21 }
22 int N,len;
23 int a[mxn],b[mxn];
24 void FWT(int *a){
25 for(int i=1;i<N;i<<=1){
26 int p=i<<1;
27 for(int j=0;j<N;j+=p){
28 for(int k=0;k<i;k++){
29 int x=a[j+k],y=a[j+k+i];
30 a[j+k]=(x+y);if(a[j+k]>=mod)a[j+k]-=mod;
31 a[j+k+i]=(x-y);if(a[j+k+i]<0)a[j+k+i]+=mod;
32 }
33 }
34 }
35 return;
36 }
37 void UTF(int *a){
38 for(int i=1;i<N;i<<=1){
39 int p=i<<1;
40 for(int j=0;j<N;j+=p){
41 for(int k=0;k<i;k++){
42 int x=a[j+k],y=a[j+k+i];
43 a[j+k]=(x+y)*(LL)inv2%mod;
44 a[j+k+i]=(x-y)*(LL)inv2%mod;
45 }
46 }
47 }
48 return;
49 }
50 int ksm(int a,int k){
51 int res=1;
52 while(k){
53 if(k&1)res=(LL)res*a%mod;
54 a=(LL)a*a%mod;
55 k>>=1;
56 }
57 return res;
58 }
59 int n,m,T;
60 int main(){
61 int i,j;
62 n=read();T=read();
63 m=1<<n;
64 for(N=1,len=0;N<=m;N<<=1)len++;
65 for(i=0;i<m;i++)a[i]=read();
66 for(i=0;i<m;i++){
67 if(i-(i&-i)==0)b[i]=1;
68 }
69 FWT(a);FWT(b);
70 for(i=0;i<N;i++)a[i]=(LL)a[i]*ksm(b[i],T)%mod;
71 UTF(a);
72 for(i=0;i<m;i++){
73 // printf("%d ",(a[i]+mod)%mod);
74 write((a[i]+mod)%mod);
75 putchar(' ');
76 }
77 return 0;
78 }
基準時間限制:2秒 空間限制:524288KB 分值:40難度:4級算法題
收藏
關注
A國是一個神奇的國家。
這個國家有2n個城市,每個城市都有一個獨一無二的編號 ,編號范圍為0~2n-1。
A國的神奇體現在,他們有著神奇的貿易規則。
當兩個城市u,v的編號滿足calc(u,v)=1的時候,這兩個城市才可以進行貿易(即有一條邊相連)。
而calc(u,v)定義為u,v按位異或的結果的二進制表示中數字1的個數。
ex:calc(1,2)=2 ——> 01 xor 10 = 11
calc(100,101)=1 ——> 0110,0100 xor 0110,0101 = 1
calc(233,233)=0 ——> 1110,1001 xor1110,1001 = 0
每個城市開始時都有不同的貨物存儲量。
而貿易的規則是:
每過一天,可以交易的城市之間就會交易一次。
在每次交易中,當前城市u中的每個貨物都將使所有與當前城市u有貿易關系的城市貨物量 +1 。
請問 t 天后,每個城市會有多少貨物。
答案可能會很大,所以請對1e9+7取模。
Input
第一行兩個正整數n,t,意義如題。 第二行2^n個非負整數,第i個數表示編號為i-1的城市的初始貨物存儲量。 n<=20t<=10^9
Output
輸出一行2^n個非負整數。 第i個數表示過了t天后,編號為i-1的城市上的貨物數量對1e9+7取模的結果。
Input示例
樣例1: 32 12345678 樣例2: 11 01
Output示例
樣例1: 5862667074788286 樣例2: 11
總結
以上是生活随笔為你收集整理的51nod1773 A国的贸易的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 留言终结者(流言终结者16季全集百度云)
- 下一篇: 獐子图片(麋鹿苑 | 獐)