日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

51nod1773 A国的贸易

發布時間:2024/4/24 综合教程 36 生活家
生活随笔 收集整理的這篇文章主要介紹了 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国的贸易的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。