String (排列组合问题)

题目链接地址:

http://acm.hdu.edu.cn/showproblem.php?pid=3398

 

对于这道题目,自己彻底无语了.........

 

首先对于这道题目,解决问题有两步

 

1) 得到公式 C(N+M,N)-C(N+M,M-1)   (利用二维坐标来看这个公式,就很明了了,从(0,0)-->(n,m))

 

2) 对于求C(N,M),有一个快速质因数分解的方法,这样就把除法变成了很好解决的幂减法问题。

倘若用 C(N+1,M+1)=C(N,M)+C(N+1,M).......显然TLE

 

当时比赛的时候,我找出了公式,但是接下来,自己就不会做了......囧

 

今天看了别人的解题报告,我也看了好久才明白那个快速质因数分解是什么意思........

 

现在有种畅快的感觉。

 

提交后,发现ac的人中,咱花的时间最高,,,,,,1800+MS

 

代码:

/*
 * File:   main.cpp
 * Author: mtttt
 *
 * Created on 2010年5月4日, 下午2:56
 */


#include <iostream>

#include <cstdlib>
using namespace std;
const int N=2000000;
const int mod=20100501;
bool ss[N+5];
int n1[N/10],n2[N/10],n3[N/10],pl[N/10];
int n,m,tot;
void prepare() //筛选法选出素数
{
    memset(ss,false,sizeof(ss));
    for(int i=2;i*i<=N;i++)
    {
        if(!ss[i])
          for(int j=2;i*j<=N;j++)
              ss[i*j]=true;
    }
    tot=0;
    for(int i=2;i<=N;i++)
        if(!ss[i]) pl[tot++]=i;
}
void Div(int *t,int k)   //k! 用 素数相乘来表示, t[i]表示 t[i]个pl[i]相乘
{
    for(int i=0;i<tot;i++) t[i]=0;
    for(int i=0;pl[i]<=k&&i<tot;i++)
    {
        int tp=k;
        while(tp/pl[i])
        {
            t[i]+=tp/pl[i];
            tp=tp/pl[i];
        }
    }
}
long long pp(long long a,long long b) // long long 型
{
    if(b==0) return 1;
    long long re=pp(a,b/2);
    re%=mod;
    re=re*re;
    re%=mod;
    if(b%2) re*=a;
    re%=mod;
    return re;
}
int main(int argc, char** argv) {
   // freopen("11.in","r",stdin);
    prepare(); // 先打表,得出素数
    int T;
    cin>>T;
    while(T--)
    {
        scanf("%d %d",&n,&m);
        Div(n1,n+m);
        Div(n2,n);
        Div(n3,m);
        for(int i=0;i<tot;i++)
            n1[i]=n1[i]-n2[i]-n3[i];  //相除 变成了 幂相减
        long long yy=1;
        for(int i=0;i<tot;i++)
        { yy*=pp(pl[i],n1[i]);
           yy%=mod;
        }
        Div(n1,n+m);
        Div(n2,n+1);
        Div(n3,m-1);
          for(int i=0;i<tot;i++)
            n1[i]=n1[i]-n2[i]-n3[i];
        long long uu=1;
        for(int i=0;i<tot;i++)
        { uu*=pp(pl[i],n1[i]);
           uu%=mod;
        }
        yy=yy-uu;
        yy=(yy+mod)%mod;
        cout<<yy<<endl;
     }
    return 1;
}

代码不优化了.....无语,太伤了

 有个极郁闷的.....就是memset(t,o,sizeof(t))....

后来改成了  for(int i=0;i<tot;i++) t[i]=0;
就对了,不然结果就错了....

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值