• 【51Nod1773】A国的贸易 解题报告


    【51Nod1773】A国的贸易

    Description

    给出一个长度为 (2^n) 的序列,编号从(0)开始。每次操作后,如果 (i)(j) 的二进制表示只差一位则第 (i) 个数会加上操作前的第 (j) 个数。求 (t) 次操作后序列中的每个数是多少。

    Input

    第一行两个正整数 (n) ,(t),意义如题。
    第二行 (2^n) 个非负整数,第 (i) 个数表示编号为 (i-1) 的城市的初始货物存储量。
    (n<=20 t<=10^9)

    Output

    输出一行 (2^n) 个非负整数。
    (i) 个数表示过了 (t) 天后,编号为 (i-1) 的城市上的货物数量对 (1e9+7) 取模的结果。


    构造一个多项式(F)(F_i=1),当(i)(2)的正整数幂的时候。

    然后答案就是(D*F^t),乘法是异或子集和,用(FWT)就可以了。

    注意到不要写多项式快速幂,子集运算的长度是封闭的,所以化成类似点乘的形式后做快速幂即可,这样复杂度是(O(n2^n))


    Code:

    #include <cstdio>
    const int N=(1<<20)+10;
    const int mod=1e9+7,inv=500000004;
    namespace Fast{
        const int LEN=10000000;
        char inp[LEN],outp[LEN];
        int tmp[20];
        int inpos,outpos;
        void init(){
            fread(inp,1,LEN,stdin);
            inpos=0; outpos=0;
        }
        char GetChar(){return inp[inpos++];}
        int read(){
            int ret=0; char ch=GetChar();
            while (ch<'0'||ch>'9') ch=GetChar();
            while ('0'<=ch&&ch<='9') ret=ret*10+ch-'0',ch=GetChar();
            return ret;
        }
        void PutChar(char ch){outp[outpos++]=ch;}
        void print(int x){
            int pos=0;
            if (!x) tmp[++pos]=0;
            else
                while (x) tmp[++pos]=x%10,x/=10;
            for (int i=pos;i>=1;--i) PutChar(tmp[i]+'0');
        }
        void Print(){fwrite(outp,1,outpos,stdout);}
    }
    #define mul(a,b) (1ll*(a)*(b)%mod)
    #define add(a,b) ((a+b)%mod)
    int n,len,t,T[N],D[N];
    void xorfwt(int *a,int typ)
    {
        for(int le=1;le<len;le<<=1)
            for(int p=0;p<len;p+=le<<1)
                for(int i=p;i<p+le;i++)
                {
                    int tx=a[i],ty=a[i+le];
                    a[i]=add(tx,ty),a[i+le]=add(tx,mod-ty);
                    if(!typ) a[i]=mul(a[i],inv),a[i+le]=mul(a[i+le],inv);
                }
    }
    int qp(int d,int k){int f=1;while(k){if(k&1)f=mul(f,d);d=mul(d,d),k>>=1;}return f;}
    int main()
    {
        Fast::init();
        n=Fast::read(),t=Fast::read(),len=1<<n;
        for(int i=0;i<len;i++) T[i]=Fast::read();
        D[0]=1;for(int i=0;i<n;i++) D[1<<i]=1;
        xorfwt(T,1),xorfwt(D,1);
        for(int i=0;i<len;i++) T[i]=mul(T[i],qp(D[i],t));
        xorfwt(T,0);
        for(int i=0;i<len;i++) Fast::print(T[i]),Fast::PutChar(' ');
        Fast::Print();
        return 0;
    }
    

    2018.12.18

  • 相关阅读:
    团队作业第四次—项目系统设计与数据库设计
    团队作业第三次—项目需求分析
    简时——alpha冲刺任务七(5.5)
    简时——alpha冲刺任务六(5.4)
    简时——alpha冲刺任务五(5.3)
    简时——alpha冲刺任务四(5.2)
    简时——alpha冲刺任务三(5.1)
    简时——alpha冲刺日志二(4.30)
    简时——alpha冲刺日志一(4.29)
    TimeMaster—代码规范、冲刺任务与计划
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10136735.html
Copyright © 2020-2023  润新知