样例三未过 玄关 生成函数做法求助
查看原帖
样例三未过 玄关 生成函数做法求助
542128
liyixin0514楼主2024/12/15 09:33

rt。

大概思路是 https://www.cnblogs.com/liyixin0514/p/18607302

萌新刚学生成函数,如果做法有冗余的地方欢迎指点。

提前拜谢大佬orz

#include<bits/stdc++.h>
#define sf scanf
#define pf printf
#define rep(x,y,z) for(int x=y;x<=z;x++)
#define per(x,y,z) for(int x=y;x>=z;x--)
using namespace std;
typedef long long ll;
namespace ababab {
    constexpr int N=1e5+7,mod=1e9+7;
    int add(int a,int b) { return a+b>=mod ? a+b-mod : a+b; }
    void _add(int &a,int b) { a=add(a,b); }
    int n,m;
    int f[N<<1],_f[N<<1];
    int lim;
    int laa,lab;
    int ans;
    void solvemul(int t) {
        memcpy(_f,f,sizeof(f));
        rep(i,0,m<<1) f[i]=add(_f[i],i-t>=0?f[i-t]:0);
    }
    void solvediv(int t) {
        memcpy(_f,f,sizeof(f));
        rep(i,0,m<<1) f[i]=add(_f[i],i-t>=0?mod-_f[i-t]:0);
    }
    void solvechange(int t) {
        memcpy(_f,f,sizeof(f));
        rep(i,0,m<<1) f[i]=i+t<=(m<<1)?f[i+t]:0;
    }
    void solvechange2(int t) {
        memcpy(_f,f,sizeof(f));
        rep(i,0,m<<1) f[i]=i-t>=0?add(_f[i-t],f[i-t]):0;
    }
    void main() {
        sf("%d%d",&n,&m);
        f[0]=1;
        lim=ceil(sqrt(m));
        // pf("%d\n",lim);
        lab=lim;
        rep(i,1,lim) solvemul(i*(i+1)/2);
        rep(a,1,min(n,lim+1)) {
            int b=n-a;
            int _a=a-1, _b=min(b,lim);
            if(laa!=_a) {
                rep(k,laa+1,_a) {
                    solvechange((k-1)*k/2);
                    solvechange2(k*(k+1)/2);
                }
                laa=_a;
            } 
            if(lab!=_b) {
                rep(k,_b+1,lab) solvediv(k*(k+1)/2);
                lab=_b;
            }
            for(int j=m;j>=0;j-=n) _add(ans,f[j]);
            // pf("%d\n",ans);
        }
        pf("%d\n",ans);
    }
}
int main() {
    #ifdef LOCAL
    freopen("in.txt","r",stdin);
    freopen("my.out","w",stdout);
    #endif
    ababab :: main();
}
2024/12/15 09:33
加载中...