BZOJ 1002: [FJOI2007]轮状病毒 高精度

有规律:$f[n]=3 imes f[n-1]-f[n-2]+2$.  

由于没有模数,所以需要写一个高精度,这里直接套用的 FFT 板子. 

code:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define ll long long 
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;     

const int N=40006;  
const double pi=acos(-1);    
char S[N]; 
struct cp
{  
    double x,y;  
    cp(double a=0,double b=0) { x=a,y=b; }   
    cp operator+(const cp b) { return cp(x+b.x,y+b.y); } 
    cp operator-(const cp b) { return cp(x-b.x,y-b.y); } 
    cp operator*(const cp b) { return cp(x*b.x-y*b.y,x*b.y+y*b.x); }
}A[N],B[N];
int mem[N*10],*ptr=mem;           
void FFT(cp *a,int len,int flag)
{
    int i,j,k,mid; 
    for(i=k=0;i<len;++i)
    {
        if(i>k) swap(a[i],a[k]);  
        for(j=len>>1;(k^=j)<j;j>>=1); 
    }
    for(mid=1;mid<len;mid<<=1)
    {
        cp wn(cos(pi/mid), flag*sin(pi/mid)),x,y;
        for(i=0;i<len;i+=mid<<1)
        {
            cp w(1,0);
            for(j=0;j<mid;++j)
            {
                x=a[i+j],y=w*a[i+j+mid]; 
                a[i+j]=x+y,a[i+j+mid]=x-y;
                w=w*wn;       
            }
        } 
    }
    if(flag==-1)
    {
        for(i=0;i<len;++i) a[i].x/=(double)len;    
    }
}
struct num
{       
    int len;
    int *a;
    num(){} 
    num(int l) { len=l,a=ptr,ptr+=l; }      
    void fix(int l) { len=l,a=ptr,ptr+=l; }         
    void get_mod(int l) { len=l; }
    num operator*(const num &b)
    {      
        num c(len+b.len+1);            
        int lim=1,i,j,l=b.len;  
        while(lim<=c.len) lim<<=1;                       
        for(i=0;i<lim;++i)
        {
            A[i].x=A[i].y=0;
            B[i].x=B[i].y=0;  
        }
        for(i=0;i<len;++i) A[i].x=a[i];   
        for(i=0;i<b.len;++i) B[i].x=b.a[i];         
        FFT(A,lim,1),FFT(B,lim,1);  
        for(i=0;i<lim;++i) A[i]=A[i]*B[i];  
        FFT(A,lim,-1);  
        for(i=0;i<c.len;++i) c.a[i]=(int)(A[i].x+0.5);   
 
        for(i=0;i<c.len-1;++i)
        {  
            c.a[i+1]+=c.a[i]/10;                
            c.a[i]%=10;     
        }
        for(i=c.len-1;i>=0;--i)  if(c.a[i]) break;             
        c.get_mod(i+1);    
        return c;  
    }         
    num operator+(const num &b) 
    {       
        num c(max(len,b.len)+1);     
        int i,j;    
        for(i=0;i<b.len;++i) c.a[i]=b.a[i];   
        for(i=0;i<len;++i) c.a[i]+=a[i];       
        for(i=0;i<c.len-1;++i) 
        {
            c.a[i+1]+=c.a[i]/10;   
            c.a[i]%=10;   
        }
        for(i=c.len-1;i>=0;--i) if(c.a[i]) break;   
        c.get_mod(i+1);      
        return c;   
    }
    num operator-(const num &b) 
    {
        num c(len);    
        int i,j;  
        for(i=0;i<len;++i) c.a[i]=a[i];   
        for(i=0;i<b.len;++i) c.a[i]-=b.a[i];        
        for(i=0;i<c.len-1;++i) 
        {
            if(c.a[i]<0) 
            {    
                c.a[i+1]-=(-c.a[i])/10+((-c.a[i])%10!=0);       
                c.a[i]=(c.a[i]%10+10)%10;       
            }   
        }
        for(i=c.len-1;i>=0;--i) if(c.a[i]) break;  
        c.get_mod(i+1);  
        return c;   
    }
    num operator/(const int b)    
    {
        num c(len);      
        int i,j,re=0;    
        for(i=len-1;i>=0;--i)
        {
            re=re*10+a[i];         
            c.a[i]=re/b;                 
            re%=b;         
        }    
        for(i=c.len-1;i>=0;--i)
        {
            if(c.a[i]) break; 
        }
        c.get_mod(i+1);  
        return c;    
    }
    void print() { for(int i=len-1;i>=0;--i) printf("%d",a[i]); }              
    void input()
    {
        scanf("%s",S);    
        int l=strlen(S);   
        fix(l);                     
        for(int i=0;i<l;++i) a[i]=S[l-1-i]-'0';    
    }  
    void modify(int x) 
    {          
        int base=1,i,j;  
        for(i=0;base<=x;++i,base*=10);    
        fix(i);  
        for(j=0;j<i;++j)  a[j]=x%10,x/=10;    
    }
}f[200],mult,add;    
ll g[N];  
int main() 
{              
    f[1].modify(1);   
    f[2].modify(5);     
    mult.modify(3);   
    add.modify(2);      
    int n,i,j;  
    scanf("%d",&n);     
    for(i=3;i<=n;++i) 
    {
       f[i]=f[i-1]*mult+add-f[i-2];     
       // g[i]=g[i-1]*3+2-g[i-2];        
    }
    f[n].print();   
    return 0;   
}

  

原文地址:https://www.cnblogs.com/guangheli/p/12257141.html