码迷,mamicode.com
首页 > 其他好文 > 详细

几个多项式的题

时间:2018-04-26 23:37:55      阅读:260      评论:0      收藏:0      [点我收藏+]

标签:sum   改变   stdout   wap   etc   sof   分享图片   \n   怎么   

4555: [Tjoi2016&Heoi2016]求和

第二类斯特林数是把n个物品分到x个无标号盒子的方案数

那么$s(i,j)*(j!)$就是把n个物品分到x个有标号的盒子的方案数

$f(n)=\sum _{j=1}^{n}s(n,j)*(j!)$

$f(n)$即把n个物品分到任意个有标号盒子的方案数

$f(i)=\sum_{j=1}^{i}C(i,j)*f(i-j)$ 枚举最后一个盒子装的球的个数

$f(n)=\sum _{j=1}^{n}s(n,j)*(j!)*(2^j)$

$f(i)=2*\sum_{j=1}^{i}C(i,j)*f(i-j)$ 多一个盒子

$f(i)/i!= \sum_{j=1}^{i}2/j!*f(i-j)/(i-j)!$

$设F(i)=f(i)/i!$

$f(i)=2/i!$

$f=f*g+1$

$(f(0)=1)$

$f=1/(1-g)$

多项式求逆即可

技术分享图片
 1 //Achen
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<vector>
 7 #include<cstdio>
 8 #include<queue>
 9 #include<cmath>
10 #include<set>
11 #include<map>
12 #define For(i,a,b) for(int i=(a);i<=(b);i++)
13 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
14 const int N=4e5+7,p=998244353,gg=3,gi=332748118;
15 typedef long long LL; 
16 typedef double db;
17 using namespace std;
18 int n;
19 LL f[N],g[N];
20 
21 template<typename T> void read(T &x) {
22     char ch=getchar(); x=0; T f=1;
23     while(ch!=-&&(ch<0||ch>9)) ch=getchar();
24     if(ch==-) f=-1,ch=getchar();
25     for(;ch>=0&&ch<=9;ch=getchar()) x=x*10+ch-0; x*=f;
26 }
27 
28 LL ksm(LL a,LL b) {
29     LL rs=1,bs=a%p;
30     while(b) {
31         if(b&1) rs=rs*bs%p;
32         bs=bs*bs%p;
33         b>>=1;
34     }
35     return rs;
36 }
37 
38 int r[N];
39 void FFT(LL a[],int n,int l,int f) {
40     For(i,0,n-1) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
41     For(i,0,n-1) if(i<r[i]) swap(a[i],a[r[i]]);
42     for(int i=1;i<n;i<<=1) {
43         LL wn=ksm((f==1?gg:gi),(p-1)/(i<<1));
44         for(int j=0,pp=(i<<1);j<n;j+=pp) {
45             LL w=1;
46             for(int k=0;k<i;k++,w=w*wn%p) {
47                 LL x=a[j+k],y=w*a[j+k+i]%p;
48                 a[j+k]=(x+y)%p; a[j+k+i]=(x-y+p)%p;
49             }
50         }
51     }
52     if(f==-1) {
53         LL inv=ksm(n,p-2);
54         For(i,0,n-1) a[i]=a[i]*inv%p;
55     }
56 }
57 
58 LL tp[N],inv[N],fac[N];
59 void get_inv(LL a[],LL b[],int n,int l) {
60     if(n==1) {
61         b[0]=ksm(a[0],p-2);
62         return;
63     }
64     get_inv(a,b,n>>1,l-1);
65     For(i,0,n-1) tp[i]=a[i],tp[i+n]=0;
66     FFT(tp,(n<<1),l+1,1);
67     FFT(b,(n<<1),l+1,1);
68     For(i,0,(n<<1)) tp[i]=(2LL-tp[i]*b[i]%p+p)%p*b[i]%p;
69     FFT(tp,(n<<1),l+1,-1);
70     For(i,0,n-1) b[i]=tp[i],b[i+n]=0;
71 }
72 
73 //#define DEBUG
74 int main() {
75 #ifdef DEBUG
76     freopen("1.in","r",stdin);
77     //freopen(".out","w",stdout);
78 #endif
79     read(n);
80        inv[0]=inv[1]=1; fac[0]=1;
81       For(i,2,n) inv[i]=p-p/i*inv[p%i]%p;
82       For(i,1,n) fac[i]=fac[i-1]*i%p,inv[i]=inv[i-1]*inv[i]%p;
83     For(i,1,n) g[i]=(p-2LL*inv[i]%p)%p; g[0]=1;
84       int nn=1,ll=0;
85       for(;nn<=n+1;nn<<=1) ll++;
86      get_inv(g,f,nn,ll);
87      LL ans=0;
88      For(i,0,nn-1) ans=(ans+f[i]*fac[i])%p;
89      printf("%lld\n",ans%p);
90     return 0;
91 }
View Code

 

3456: 城市规划

求n个点的简单(无重边无自环)无向连通图数目.

$f(n)表示n个点的简单无向图的个数$

$f(n)=2^{C(n,2)}$

$g(n)表示n个点的简单无向连通图的个数$

$f(n)=\sum_{i=1}^nC(n-1,i-1)*g(i)*f(n-i)$

(枚举1所在联通块的大小)

$f(n)/(n-1)!=\sum_{i=1}^ng(i)/(i-1)!*f(n-i)/(n-i)!$

$设F(n)=f(n)/(n-1)$

$G(n)=g(n)/(n-1)!$

$H(n)=f(n)/n!$

$F=G*H$

$G=F/H$

多项式求逆

技术分享图片
  1 //Achen
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdlib>
  6 #include<vector>
  7 #include<cstdio>
  8 #include<queue>
  9 #include<cmath>
 10 #include<set>
 11 #include<map>
 12 const int N=1621470,p=1004535809,gg=3,gi=334845270;
 13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
 14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
 15 typedef long long LL; 
 16 typedef double db;
 17 using namespace std;
 18 int n;
 19 LL g[N],h[N],h_inv[N],fac[N],inv[N];
 20 
 21 template<typename T> void read(T &x) {
 22     char ch=getchar(); x=0; T f=1;
 23     while(ch!=-&&(ch<0||ch>9)) ch=getchar();
 24     if(ch==-) f=-1,ch=getchar();
 25     for(;ch>=0&&ch<=9;ch=getchar()) x=x*10+ch-0; x*=f;
 26 }
 27 
 28 LL ksm(LL a,LL b) {
 29     LL rs=1,bs=a%p;
 30     while(b) {
 31         if(b&1) rs=rs*bs%p;
 32         bs=bs*bs%p;
 33         b>>=1;
 34     }
 35     return rs;
 36 }
 37 
 38 
 39 int r[N];
 40 void FFT(LL a[],int n,int l,int f) {
 41     For(i,0,n-1) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
 42     For(i,0,n-1) if(i<r[i]) swap(a[i],a[r[i]]);
 43     for(int i=1;i<n;i<<=1) {
 44         LL wn=ksm((f==1?gg:gi),(p-1)/(i<<1));
 45         for(int j=0,pp=(i<<1);j<n;j+=pp) {
 46             LL w=1;
 47             for(int k=0;k<i;k++,w=w*wn%p) {
 48                 LL x=a[j+k],y=w*a[j+k+i]%p;
 49                 a[j+k]=(x+y)%p; a[j+k+i]=(x-y+p)%p;
 50             }
 51         }
 52     }
 53     if(f==-1) {
 54         LL inv=ksm(n,p-2);
 55         For(i,0,n-1) a[i]=a[i]*inv%p;
 56     }
 57 }
 58 
 59 LL tp[N];
 60 void get_inv(LL a[],LL b[],int n,int l) {
 61     if(n==1) {
 62         b[0]=ksm(a[0],p-2);
 63         return;
 64     }
 65     get_inv(a,b,n>>1,l-1);
 66     For(i,0,n-1) tp[i]=a[i],tp[i+n]=0;
 67     FFT(tp,(n<<1),l+1,1);
 68     FFT(b,(n<<1),l+1,1);
 69     For(i,0,(n<<1)) tp[i]=(2LL-tp[i]*b[i]%p+p)%p*b[i]%p;
 70     FFT(tp,(n<<1),l+1,-1);
 71     For(i,0,n-1) b[i]=tp[i],b[i+n]=0;
 72 }
 73 
 74 LL C(int n,int m) { if(m<0||n<m) return 0; return fac[n]*inv[m]%p*inv[n-m]%p; }
 75 
 76 //#define DEBUG
 77 int main() {
 78 #ifdef DEBUG
 79     freopen("1.in","r",stdin);
 80     //freopen(".out","w",stdout);
 81 #endif
 82     read(n);
 83     fac[0]=1; inv[0]=inv[1]=1;
 84     For(i,2,n+1) inv[i]=p-p/i*inv[p%i]%p;
 85     For(i,1,n+1) fac[i]=fac[i-1]*i%p,inv[i]=inv[i-1]*inv[i]%p;
 86     For(i,0,n) {
 87         LL tp=ksm(2,((LL)i*(i-1)/2)%(p-1));
 88         if(i) g[i]=tp*inv[i-1]%p;
 89         h[i]=tp*inv[i]%p;
 90     }
 91     //For(i,0,n) printf("%lld ",g[i]); puts("");
 92     //For(i,0,n) printf("%lld ",h[i]); puts("");
 93     int nn=1,ll=0;
 94     for(;nn<=2*(n+1);nn<<=1) ll++;
 95     get_inv(h,h_inv,nn>>1,ll-1);
 96     //For(i,0,n) printf("%lld ",h_inv[i]); puts("");
 97     FFT(h_inv,nn,ll,1); FFT(g,nn,ll,1);
 98     For(i,0,nn) g[i]=g[i]*h_inv[i]%p;
 99     FFT(g,nn,ll,-1);
100     //For(i,0,100) printf("%lld ",g[i]); puts("");
101     printf("%lld\n",g[n]*fac[n-1]%p);
102     return 0;
103 }
View Code

 

3625: [Codeforces Round #250]小朋友和二叉树

$设c的生成函数为g$

$神犇二叉树的个数的生成函数为f$

$有f=f*f*g+1$ (空节点)

$f=(1+sqrt(1-4*g))/2*g$

$或f=(1-sqrt(1-4*g))/2*g$

$g(0)=0(c>1),所以上面1的常数项一定是取减号后抵消了$

$f=(1+sqrt(1-4*g))/2*g$

多项式开根。
牛顿迭代。

因为常数不优秀,cf上可以过,bz上会t

技术分享图片
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
#include<map>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int N=4e5+7,p=998244353,gg=3,gi=332748118;
typedef long long LL; 
typedef double db;
using namespace std;
int n,m;
LL h[N],g[N],inv_2;

template<typename T> void read(T &x) {
    char ch=getchar(); x=0; T f=1;
    while(ch!=-&&(ch<0||ch>9)) ch=getchar();
    if(ch==-) f=-1,ch=getchar();
    for(;ch>=0&&ch<=9;ch=getchar()) x=x*10+ch-0; x*=f;
}

LL ksm(LL a,LL b) {
    LL rs=1,bs=a%p;
    while(b) {
        if(b&1) rs=rs*bs%p;
        bs=bs*bs%p;
        b>>=1;
    }
    return rs;
}

void FFT(LL a[],int n,int l,int f) {
    static int r[N];
    For(i,0,n-1) r[i]=(r[i>>1]>>1)|((i&1)<<l-1);
    For(i,0,n-1) if(i<r[i]) swap(a[i],a[r[i]]);
    for(int i=1;i<n;i<<=1) {
        LL wn=ksm((f==1?gg:gi),(p-1)/(i<<1));
        for(int j=0,pp=(i<<1);j<n;j+=pp) {
            LL w=1;
            for(int k=0;k<i;k++,w=w*wn%p) {
                LL x=a[j+k]%p,y=a[j+k+i]*w%p;
                a[j+k]=(x+y)%p,a[j+k+i]=(x-y+p)%p;
            }
        }
    }
    if(f==-1) {
        LL invv=ksm(n,p-2);
        For(i,0,n-1) a[i]=a[i]*invv%p;
    }
}

LL tp[N],h_inv[N];
void get_inv(LL a[],LL b[],int n,int l) {
    if(n==1) {
        b[0]=ksm(a[0],p-2); 
        return ;
    }
    get_inv(a,b,n>>1,l-1);
    For(i,0,n-1) tp[i]=a[i],tp[i+n]=0;
    FFT(tp,n<<1,l+1,1);
    FFT(b,n<<1,l+1,1);
    For(i,0,n<<1) tp[i]=(2LL-tp[i]*b[i]%p+p)%p*b[i]%p;
    FFT(tp,n<<1,l+1,-1);
    For(i,0,n-1) b[i]=tp[i],b[i+n]=0; 
}

LL h_sqr[N],a_t[N],b_t[N];
void get_sqr(LL a[],LL b[],int n,int l) {
    if(n==1) {
        b[0]=sqrt(a[0]);
        return;
    }
    get_sqr(a,b,n>>1,l-1);
    For(i,0,n<<1) b_t[i]=0;
    For(i,0,n-1) a_t[i]=a[i],a_t[i+n]=0;
    get_inv(b,b_t,n,l);
    FFT(b,n<<1,l+1,1);
    FFT(a_t,n<<1,l+1,1);
    FFT(b_t,n<<1,l+1,1);
    For(i,0,n<<1) b[i]=(b[i]+a_t[i]*b_t[i]%p)%p*inv_2%p;
    FFT(b,n<<1,l+1,-1);
    For(i,0,n-1) b[n+i]=0;
}

//#define DEBUG
int main() {
#ifdef DEBUG
    freopen("1.in","r",stdin);
    //freopen(".out","w",stdout);
#endif
    read(n); read(m);
    inv_2=ksm(2,p-2);
    For(i,1,n) {
        int x; read(x); g[x]++;
    }
    h[0]=1;
    For(i,1,m) if(g[i]) h[i]=(p-4LL*g[i]%p)%p;
    int nn=1,ll=0;
    for(;nn<=m+1;nn<<=1) ll++;
    get_sqr(h,h_sqr,nn,ll);
    h_sqr[0]=(h_sqr[0]+1)%p;
    get_inv(h_sqr,h_inv,nn,ll);
    For(i,1,m) printf("%I64d\n",(h_inv[i]+h_inv[i])%p);
    return 0;
}
View Code

 

我真是蠢到不行,遇见式子不要感觉有一点不对劲就盯着它发呆,你好歹去把它化一化啊,多半化一化就出来了,脑子是木的吗我。

 

 

最近感觉很不对劲

不应该是这样的

不应该是现在这个样子

各方面都是

为什么是这样啊

是哪里不对劲吧

到底是哪个地方出了问题呀

 

可能这周心都已经不在机房了

或者说省选以来都是这样

不管怎么说

终于要回家了

回家之后或许会有什么变化吧

不能这样下去

bad end的flag已经高高立起了

一定要改变一点什么才行呀

几个多项式的题

标签:sum   改变   stdout   wap   etc   sof   分享图片   \n   怎么   

原文地址:https://www.cnblogs.com/Achenchen/p/8955179.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!