zoukankan      html  css  js  c++  java
  • 【BZOJ5300】[CQOI2018]九连环 (高精度,FFT)

    【BZOJ5300】[CQOI2018]九连环 (高精度,FFT)

    题面

    BZOJ
    洛谷

    题解

    去这里看吧,多么好

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    using namespace std;
    #define MAX 150000
    const double Pi=acos(-1);
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    struct Complex{double a,b;}A[MAX],B[MAX],W[MAX];
    Complex operator+(Complex a,Complex b){return (Complex){a.a+b.a,a.b+b.b};}
    Complex operator-(Complex a,Complex b){return (Complex){a.a-b.a,a.b-b.b};}
    Complex operator*(Complex a,Complex b){return (Complex){a.a*b.a-a.b*b.b,a.b*b.a+a.a*b.b};}
    int r[MAX],N,l=0;
    void FFT(Complex *P,int N,int opt)
    {
        for(int i=0;i<N;++i)if(i<r[i])swap(P[i],P[r[i]]);
        for(int i=1;i<N;i<<=1)
            for(int p=i<<1,j=0;j<N;j+=p)
                for(int k=0;k<i;++k)
                {
                    Complex w=W[N/i*k];w.b*=opt;
                    Complex X=P[j+k],Y=P[i+j+k]*w;
                    P[j+k]=X+Y;P[i+j+k]=X-Y;
                }
        if(opt==-1)for(int i=0;i<N;++i)P[i].a/=N;
    }
    int Multi(int *a,int *b,int n,int m,int *c)
    {
        l=0;for(N=1;N<=n+m;N<<=1)++l;
        for(int i=0;i<N;++i)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
        for(int i=1;i<N;i<<=1)
            for(int k=0;k<i;++k)
                W[N/i*k]=(Complex){cos(Pi/i*k),sin(Pi/i*k)};
        for(int i=0;i<=n;++i)A[i].a=a[i];
        for(int i=0;i<=m;++i)B[i].a=b[i];
        FFT(A,N,1);FFT(B,N,1);
        for(int i=0;i<N;++i)A[i]=A[i]*B[i];
        FFT(A,N,-1);
        for(int i=0;i<=n+m;++i)c[i]=A[i].a+0.5;
        for(int i=0;i<N;++i)A[i]=B[i]=(Complex){0,0};
    	int len=n+m;
    	for(int i=0;i<=len;++i)c[i+1]+=c[i]/10,c[i]%=10;
    	while(c[len+1])++len,c[len+1]+=c[len]/10,c[len]%=10;
    	return len;
    }
    int a[MAX],b[MAX],c[MAX];
    int main()
    {
    	int T=read();
    	while(T--)
    	{
    		int n=read()+1;
    		memset(a,0,sizeof(a));memset(b,0,sizeof(b));
    		int la=0,lb=0;a[0]=1;b[0]=2;
    		while(n)
    		{
    			if(n&1)la=Multi(a,b,la,lb,a);
    			lb=Multi(b,b,lb,lb,b);
    			n>>=1;
    		}
    		bool o=false;int s=0;
    		for(int i=la;~i;--i)
    		{
    			s=s*10+a[i];
    			if(s<3&&!o)continue;
    			o=true;printf("%d",s/3);s%=3;
    		}
    		puts("");
    	}
    }
    
  • 相关阅读:
    C#中的委托是什么?事件是不是一种委托?
    SQL重点复习
    数据库生成脚本
    用Winfrom动态生成SQL的insert语句
    如何实现远程连接SQL Server 2008 Express
    跨页面传送
    win7 防火墙开启ping
    关于*.class和*.jar的几个基本认识
    使用cobertura确定测试代码的覆盖率
    Java学习笔记之I/O
  • 原文地址:https://www.cnblogs.com/cjyyb/p/10403464.html
Copyright © 2011-2022 走看看