zoukankan      html  css  js  c++  java
  • 51nod1773 A国的贸易

    基准时间限制:2 秒 空间限制:524288 KB 分值: 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 xor 1110,1001 = 0

    每个城市开始时都有不同的货物存储量。
    而贸易的规则是:
    每过一天,可以交易的城市之间就会交易一次。
    在每次交易中,当前城市u中的每个货物都将使所有与当前城市u有贸易关系的城市货物量 +1 。
    请问 t 天后,每个城市会有多少货物。
    答案可能会很大,所以请对1e9+7取模。
     
    Input
    第一行两个正整数 n , t,意义如题。
    第二行 2^n 个非负整数,第 i 个数表示编号为 i-1 的城市的初始货物存储量。
    n<=20  t<=10^9
    Output
    输出一行 2^n 个非负整数。
    第 i 个数表示过了 t 天后,编号为 i-1 的城市上的货物数量对 1e9+7 取模的结果。
    Input示例
    样例1:
    3 2
    1 2 3 4 5 6 7 8
    样例2:
    1 1
    0 1
    Output示例
    样例1:
    58 62 66 70 74 78 82 86
    样例2:
    1 1

    动态规划 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 秒 空间限制:524288 KB 分值: 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 xor 1110,1001 = 0

    每个城市开始时都有不同的货物存储量。
    而贸易的规则是:
    每过一天,可以交易的城市之间就会交易一次。
    在每次交易中,当前城市u中的每个货物都将使所有与当前城市u有贸易关系的城市货物量 +1 。
    请问 t 天后,每个城市会有多少货物。
    答案可能会很大,所以请对1e9+7取模。
     
    Input
    第一行两个正整数 n , t,意义如题。
    第二行 2^n 个非负整数,第 i 个数表示编号为 i-1 的城市的初始货物存储量。
    n<=20  t<=10^9
    Output
    输出一行 2^n 个非负整数。
    第 i 个数表示过了 t 天后,编号为 i-1 的城市上的货物数量对 1e9+7 取模的结果。
    Input示例
    样例1:
    3 2
    1 2 3 4 5 6 7 8
    样例2:
    1 1
    0 1
    Output示例
    样例1:
    58 62 66 70 74 78 82 86
    样例2:
    1 1
  • 相关阅读:
    Spring Boot教程(三十)使用Spring-data-jpa(1)
    Spring Boot教程(二十九)使用JdbcTemplate操作数据库
    Spring Boot教程(二十八)通过JdbcTemplate编写数据访问
    Spring Boot教程(二十七)整合Spring Security
    Spring Boot教程(二十六)使用Spring Security安全控制
    Spring Boot教程(二十五)返回JSON格式
    gl 绘制多边形的函数解析 分类: OpenGL(转)
    OpenGL超级宝典笔记——画三角形(转)
    OpenGL_Qt学习笔记之_03(平面图形的着色和旋转)(转)
    OpenGL超级宝典笔记——贝塞尔曲线和曲面(转)
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/7118689.html
Copyright © 2011-2022 走看看