zoukankan      html  css  js  c++  java
  • 洛谷P1771 方程的解_NOI导刊2010提高(01)

    题目描述

    佳佳碰到了一个难题,请你来帮忙解决。

    对于不定方程a1+a2+…+ak-1+ak=g(x),其中k≥2且k∈N,x是正整数,g(x)=x^x mod 1000(即x^x除以1000的余数),x,k是给定的数。我们要求的是这个不定方程的正整数解组数。

    举例来说,当k=3,x=2时,分别为(a1,a2,a3)=(2,1,1)'(1,2,1),(1,1,2)。

    输入输出格式

    输入格式:

    输入文件equation.in有且只有一行,为用空格隔开的两个正整数,依次为k,x。

    输出格式:

    输出文件equation.out有且只有一行,为方程的正整数解组数。

    输入输出样例

    输入样例#1:
    3 2
    输出样例#1:
    3

    说明

    对于40%的数据,ans≤10^16;对于100%的数据,k≤100,x≤2^31-1,k≤g(x)。

    _NOI导刊2010提高(01)

    分析:考虑dp,设f[i][j]表示选了i个数,和为j的正整数解组数.很显然f[i][j]=∑f[i-1][j-kk],kk是i能够取到的数,答案是f[x^x % 1000][k].复杂度是三次方级别的,看有没有方方法来优化一下.单纯从dp上来看似乎是只能优化空间了,如果有公式就好了,类似青蛙过河一样。

          其实问题可以变成我们要走k步,每一步走的距离任意,走的总距离要为x,求方案数,因为每一步走的距离任意,实际上我们只要把这k步分配到x中就好了.把x抽象成x个点,画在图上,就能发现走k步实际上是在x-1个间隔中找k-1个间隔,那么答案就是C(x-1,k-1).

    因为k,x很大,所以要用到高精度,我用结构体写高精度总是出现奇怪的错误,以后还是用数组了.

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    long long k,x;
    int f[1000][110][220];
    
    long long qpow(long long a,long long b,int mod)
    {
        long long ans = 1;
        while (b)
        {
            if (b & 1)
            ans = (ans * a) % mod;
            a = (a * a) % mod;
            b >>= 1;
        }
        return ans;
    }
    
    void add(int x,int y,int x1,int y1,int x2,int y2)
    {
        for (int i = 1; i <= max(f[x1][y1][0],f[x2][y2][0]); i++)
        {
            f[x][y][i] += f[x1][y1][i] + f[x2][y2][i];
            f[x][y][i + 1] = f[x][y][i] / 10;
            f[x][y][i] %= 10;
        }
        f[x][y][0] = max(f[x1][y1][0],f[x2][y2][0]);
        if (f[x][y][f[x][y][0] + 1])
        f[x][y][0]++;
    }
    
    int main()
    {
        scanf("%lld%lld",&k,&x);
        x = qpow(x,x,1000);
        
        for (int i = 0; i < x; i++)
        f[i][0][0] = f[i][0][1] = 1;
        
        for (int i = 1; i < x; i++)
        for (int j = 1; j < k; j++)
        add(i,j,i-1,j,i-1,j-1);
        
        for (int i = f[x-1][k-1][0]; i >= 1; i--)
        printf("%d",f[x-1][k-1][i]);
        printf("
    ");
        
        return 0;
    }
  • 相关阅读:
    jquery笔记
    JavaScript 运动框架 Step by step(转)
    js中获取页面元素方法总结
    图片缩放效果IE和火狐兼容模式
    js循环运动效果实现
    网页捕捉错误
    (图文介绍)Virtualbox下实现Ubuntu虚拟机和win7主机文件共享(很简单,亲自试用,按此步骤一般都会成功)
    FFT算法实现(fft算法)快速傅里叶变换算法实现
    $_SESSION跨页面问题
    暂别ACM,转移阵地
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7494864.html
Copyright © 2011-2022 走看看