zoukankan      html  css  js  c++  java
  • BZOJ 1498: [NOI2006]神奇的口袋 性质分析+高精度

    我们发现我们可以直接让 $x_{i}=i$,然后模拟就行了. 

    code: 

    #include <cstdio> 
    #include <cstring> 
    #include <cmath> 
    #include <vector>    
    #include <map>   
    #include <algorithm> 
    #define N 500005   
    #define ll long long 
    #define setIO(s) freopen(s".in","r",stdin)  ,freopen(s".out","w",stdout)   
    using namespace std;
    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;   
        }
    };   
    int a[N],mul[N],dn[N];    
    void calc(int x,int *arr) 
    { 
        int i,j; 
        for(i=2;i<=x;++i) 
        {
            if(x%i==0) 
            {      
                while(x%i==0) x/=i,arr[i]++;    
            }
        }    
        if(x) arr[x]++;    
    }
    int main() 
    { 
        // setIO("input");  
        int i,j,t,n,d,sum=0;   
        scanf("%d%d%d",&t,&n,&d);         
        for(i=1;i<=t;++i)  scanf("%d",&a[i]),sum+=a[i];   
        for(i=1;i<=n;++i)  
        {
            int x,y; 
            scanf("%d%d",&x,&y);   
            if(!a[y])  { printf("0/1
    "); return 0; }                
            calc(a[y],mul);   
            calc(sum,dn);    
            sum+=d; 
            a[y]+=d; 
        }   
        for(i=2;i<N;++i) 
        { 
            int tmp=min(mul[i],dn[i]); 
            mul[i]-=tmp; 
            dn[i]-=tmp;  
        }   
    
        num ans,det; 
        ans.modify(1);  
        for(i=2;i<N;++i) 
        {   
            det.modify(i); 
            for(j=1;j<=mul[i];++j) ans=ans*det;    
        } 
        ans.print();   
        printf("/");    
        ans.modify(1);         
        for(i=2;i<N;++i) 
        {
            if(!dn[i]) continue;   
            det.modify(i);    
            for(j=1;j<=dn[i];++j) ans=ans*det; 
        }    
        ans.print();                 
        return 0; 
    }
    

      

  • 相关阅读:
    求一个电子书制作的好方法
    解决windows xp系统,报iis提示访问人数过多错误
    DEVELOPER: ODP.NET Instant ODP.NET Deployment
    重新注册Oracle相关库
    ODP.NET调用存储需要使用事务
    ReportViewer在设计报告参数(SetParameter)时线程挂起(hang)
    js 时间
    验证码
    script标签属性用type还是language?
    iScroll框架的修改
  • 原文地址:https://www.cnblogs.com/guangheli/p/12295388.html
Copyright © 2011-2022 走看看