P4705 玩游戏
思路
超级麻烦。。。
写了一堆最后常数太大T飞了。。。
真的难受
发现solve函数可以不用把下一层复制上来,直接传指针就可以,下次再说写不写叭
思路
\]
二项式定理拆一下式子
\]
所以只要求出\(\sum_i a_i^k\)即可
对\(a_i\),设其生成函数\(A(x)=1+a_ix+a_i^2x^2+a_i^3x^3+\dots\)
\]
最后答案的生成函数\(G(x)\)就是\(\sum_{i=0}^n A_i(x)\)
然后一个常见套路就是把\(\frac{1}{x}\)用\(\ln 'x\)代替
所以有
\]
但是这样依然无法快速计算
我们可以再设一个\(F(x)\)
G(x)=\sum_{i=1}^n \frac{1}{1-a_ix}
\]
所以\(G(x)=-xF(x)+n\)
然后对于\(F(x)\),
\]
分治加NTT就可以在\(O(n\log^2n)\)的时间内解决
常数过大T掉的代码
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <assert.h>
#define int long long
using namespace std;
const int MAXN = 600000;
const int MAXL = 100100;
const int G = 3;
const int invG = 332748118;
const int MOD = 998244353;
const int InputBufferSize = 67108864;//输入缓冲区大小
const int OutputBufferSize = 67108864;//输出缓冲区大小 
namespace input
{
    char buffer[InputBufferSize],*s,*eof;
    inline void init()
    {
        assert(stdin!=NULL);
        s=buffer;
        eof=s+fread(buffer,1,InputBufferSize,stdin);
    }
    inline bool read(int &x)
    {
        x=0;
        int flag=1;
        while(!isdigit(*s)&&*s!='-')s++;
        if(eof<=s)return false;
        if(*s=='-')flag=-1,s++;
        while(isdigit(*s))x=x*10+*s++-'0';
        x*=flag;
        return true;
    }
    inline bool read(char* str)
    {
        *str=0;
        while(isspace(*s))s++;
        if(eof<s)return false;
        while(!isspace(*s))*str=0,*str=*s,str++,s++;
        *str=0;
        return true;
    }
}
namespace output
{
    char buffer[OutputBufferSize];
    char *s=buffer;
    inline void flush()
    {
        assert(stdout!=NULL);
        fwrite(buffer,1,s-buffer,stdout);
        s=buffer;
        fflush(stdout);
    }
    inline void print(const char ch)
    {
        if(s-buffer>OutputBufferSize-2)flush();
        *s++=ch;
    }
    inline void print(char* str)
    {
        while(*str!=0)print(char(*str++));
    }
    inline void print(int x)
    {
        char buf[25]= {0},*p=buf;
        if(x<0)print('-'),x=-x;
        if(x==0)print('0');
        while(x)*(++p)=x%10,x/=10;
        while(p!=buf)print(char(*(p--)+'0'));
    }
}
using namespace input;
using namespace output;
int pow(int a,int b){
    int ans=1;
    while(b){
        if(b&1)
            ans=(1LL*ans*a)%MOD;
        a=(1LL*a*a)%MOD;
        b>>=1;
    }
    return ans;
}
void FFT(int *a,int n,int opt,int lim){
    for(int i=0;i<n;++i){
        int t=0;
        for(int j=0;j<lim;++j)
            if((i>>j)&1)
                t|=(1LL<<(lim-j-1));
        if(i<t)
            swap(a[i],a[t]);
    }
    for(int i=2;i<=n;i<<=1){
        int len=i/2;
        int tmp=pow((opt)?G:invG,(MOD-1)/i);
        for(int j=0;j<n;j+=i){
            int arr=1;
            for(int k=j;k<j+len;++k){
                int t=(1LL*a[k+len]*arr)%MOD;
                a[k+len]=(a[k]-t+MOD)%MOD;
                a[k]=(a[k]+t)%MOD;
                arr=(1LL*arr*tmp)%MOD;;
            }
        }
    }
    if(!opt){
        int invN=pow(n,MOD-2);
        for(int i=0;i<n;++i)
            a[i]=1LL*a[i]*invN%MOD;
    }
}
void mul(int *a,int *bx,int &at,int bt){
    static int b[MAXN];
    int lim=0,num=at+bt,logt;
    while((1<<lim)<=(num+2))
        lim++;
    logt=lim;
    lim=(1<<lim);
    for(int i=0;i<lim;++i)
        b[i]=bx[i];
    FFT(a,lim,1,logt);
    FFT(b,lim,1,logt);
    for(int i=0;i<lim;++i)
        a[i]=(1LL*a[i]*b[i])%MOD;
    FFT(a,lim,0,logt);
    for(int i=num+1;i<lim;++i)
        a[i]=0;
    at=num;
}
void inv(int *a,int *b,int &bt,int dep,int &midlen,int &logt){
    if(dep==1){
        b[0]=pow(a[0],MOD-2);
        bt=0;
        return;
    }
    inv(a,b,bt,(dep+1)>>1,midlen,logt);
    static int tmp1[MAXN];
    for(int i=0;i<dep;++i)
        tmp1[i]=a[i];
    while((dep<<1)>midlen)
        midlen<<=1,logt++;
    for(int i=dep;i<midlen;++i)
        tmp1[i]=0;
    FFT(tmp1,midlen,1,logt);
    FFT(b,midlen,1,logt);
    for(int i=0;i<midlen;++i)
        b[i]=1LL*b[i]*(2-1LL*tmp1[i]*b[i]%MOD+MOD)%MOD;
    FFT(b,midlen,0,logt);
    for(int i=dep;i<midlen;++i)
        b[i]=0;
    bt=dep-1;
}
void jf(int *a,int &at){
    for(int i=at;i>=0;--i)
        a[i+1]=(1LL*a[i]*pow(i+1,MOD-2))%MOD;
    a[0]=0;
    at++;
}
void qd(int *a,int &at){
    for(int i=0;i<at;++i)
        a[i]=(1LL*a[i+1]*(i+1))%MOD;
    a[at]=0;
    at--;
}
void ln(int *a,int *b,int at,int &bt,int n){
    int midlen=1,logt=0;
    inv(a,b,bt,at+1,midlen,logt);
    qd(a,at);
    mul(b,a,bt,at);
    jf(b,bt);
    for(int i=n;i<=bt;++i)
        b[i]=0;
    bt=n-1;
}
int val[MAXL];
int P[20][MAXN],Pt[20];
void solve(int l,int r,int dep){
    if(l==r){
        for(int i=2;i<=Pt[dep];++i)
            P[dep][i]=0;
        P[dep][0]=1;
        P[dep][1]=MOD-val[l];
        Pt[dep]=1;
        return;
    }
    int mid=(l+r)>>1;
    solve(l,mid,dep+1);
    for(int i=0;i<=Pt[dep+1];++i)
        P[dep][i]=P[dep+1][i];
    for(int i=Pt[dep+1]+1;i<=Pt[dep];++i)
        P[dep][i]=0;
    Pt[dep]=Pt[dep+1];
    solve(mid+1,r,dep+1);
    mul(P[dep],P[dep+1],Pt[dep],Pt[dep+1]);
}
int jc[MAXL],jc_inv[MAXL];
int n,m,t;
void initx(void){
    jc[0]=1;
    int up=max(max(n,m),t)+1;
    for(int i=1;i<up;++i)
        jc[i]=(1LL*jc[i-1]*i)%MOD;
    jc_inv[up-1]=pow(jc[up-1],MOD-2);
    for(int i=up-2;i>=0;--i){
        jc_inv[i]=(1LL*jc_inv[i+1]*(i+1))%MOD;
    }
}
void getf(int *b,int &bt,int n){
    solve(1,n,0);
    int midlen=1,midlog=0;
    Pt[0]=max(n+1,1LL*t+1);
    inv(P[0],b,bt,Pt[0]+1,midlen,midlog);
    qd(P[0],Pt[0]);
    mul(b,P[0],bt,Pt[0]);
    for(int i=bt;i>=0;--i)
        b[i+1]=MOD-b[i];
    b[0]=n;
    for(int i=0;i<=bt;++i){
        b[i]=(1LL*b[i]*jc_inv[i])%MOD;
    }
}
int ap[MAXN],bp[MAXN];
int ax[MAXL],bx[MAXL];
signed main(){
    freopen("test.in","r",stdin);
    freopen("test.out","w",stdout);
    // scanf("%d %d",&n,&m);
    init();
    read(n);
    read(m);
    for(int i=1;i<=n;++i)
        read(ax[i]);
        // scanf("%d",&ax[i]);
    for(int i=1;i<=m;++i)
        read(bx[i]);
        // scanf("%d",&bx[i]);
    // scanf("%d",&t);
    read(t);
    initx();
    for(int i=1;i<=n;++i)
        val[i]=ax[i];
    int apt=0,bpt=0;
    getf(ap,apt,n);
    for(int i=1;i<=m;++i)
        val[i]=bx[i];
    getf(bp,bpt,m);
    mul(ap,bp,apt,bpt);
    int n_inv=pow(n,MOD-2),m_inv=pow(m,MOD-2);
    for(int i=1;i<=t;++i){
        print(1LL*jc[i]*ap[i]%MOD*n_inv%MOD*m_inv%MOD);
        print('\n');
    }
    flush();
    return 0;
}
P4705 玩游戏的更多相关文章
- 洛谷 P4705 玩游戏 解题报告
		P4705 玩游戏 题意:给长为\(n\)的\(\{a_i\}\)和长为\(m\)的\(\{b_i\}\),设 \[ f(x)=\sum_{k\ge 0}\sum_{i=1}^n\sum_{j=1}^ ... 
- Luogu P4705 玩游戏
		题目描述 Alice 和 Bob 又在玩游戏. 对于一次游戏,首先 Alice 获得一个长度为  的序列 ,Bob 获得一个长度为  的序列 bb.之后他们各从自己的序列里随机取出一个数,分别设 ... 
- 洛谷P4705 玩游戏 [生成函数,NTT]
		传送门 这是两个月之前写的题,但没写博客.现在回过头来看一下发现又不会了-- 还是要写博客加深记忆. 思路 显然期望可以算出总数再乘上\((nm)^{-1}\). 那么有 \[ \begin{alig ... 
- [洛谷P4705]玩游戏
		题目大意:对于每个$k\in[1,t]$,求:$$\dfrac{\sum\limits_{i=1}^n\sum\limits_{j=1}^m(a_i+b_j)^k}{nm}$$$n,m,t\leqsl ... 
- 洛谷 P4705 玩游戏
		题目分析 题目要求的是: \[ \sum_{i=1}^n\sum_{j=1}^m(a_i+b_j)^x(x\in [1,T]) \] 利用二项式定理化式子, \[ \begin{aligned} &a ... 
- 洛谷P4705 玩游戏(生成函数+多项式运算)
		题面 传送门 题解 妈呀这辣鸡题目调了我整整三天--最后发现竟然是因为分治\(NTT\)之后的多项式长度不是\(2\)的幂导致把多项式的值存下来的时候发生了一些玄学错误--玄学到了我\(WA\)的点全 ... 
- 原生JS实战:写了个一边玩游戏,一边记JS的API的游戏
		本文是苏福的原创文章,转载请注明出处:苏福CNblog:http://www.cnblogs.com/susufufu/p/5878913.html 本程序[一边玩游戏,一边记JS的API]是本人的个 ... 
- bzoj4730: Alice和Bob又在玩游戏
		Description Alice和Bob在玩游戏.有n个节点,m条边(0<=m<=n-1),构成若干棵有根树,每棵树的根节点是该连通块内编号最 小的点.Alice和Bob轮流操作,每回合 ... 
- 小易邀请你玩一个数字游戏,小易给你一系列的整数。你们俩使用这些整数玩游戏。每次小易会任意说一个数字出来,然后你需要从这一系列数字中选取一部分出来让它们的和等于小易所说的数字。 例如: 如果{2,1,2,7}是你有的一系列数,小易说的数字是11.你可以得到方案2+2+7 = 11.如果顽皮的小易想坑你,他说的数字是6,那么你没有办法拼凑出和为6 现在小易给你n个数,让你找出无法从n个数中选取部分求和
		小易邀请你玩一个数字游戏,小易给你一系列的整数.你们俩使用这些整数玩游戏.每次小易会任意说一个数字出来,然后你需要从这一系列数字中选取一部分出来让它们的和等于小易所说的数字. 例如: 如果{2,1,2 ... 
随机推荐
- python 函数enumerate(x,y)的用法
			enumerate(x,y)函数是把元组tuple.字符串str.列表list里面的元素遍历和索引组合,其用法与range()函数很相似, 下面示例enumerate(x,y)用法以及range(x) ... 
- [LeetCode] 132. Palindrome Partitioning II_ Hard tag: Dynamic Programming
			Given a string s, partition s such that every substring of the partition is a palindrome. Return the ... 
- 2018-2019-2 网络对抗技术 20165321 Exp4 恶意代码分析
			1.实践目标 1.1是监控你自己系统的运行状态,看有没有可疑的程序在运行. 1.2是分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生指令或sysinternals,sys ... 
- CDIE2019中国数字化创新展暨首席信息官峰会上海站来袭~
			China Digital Innovation Expo & CIO Summit 2019是由Dot Connector(上海华昂商务咨询有限公司)主办的第五届聚焦中国技术领袖,探索创新, ... 
- springmvc中的一些服务器报错
			这是springmvc的前端控制器的加载格式要求.服务器加载web.xml后,它会在web-inf/下找名为spring[servlet名/handler处理器名]-servlet.xml文件. 可以 ... 
- Qt QSpinBox  和 QDoubleSpinBox
			展示一个效果: QDoubleSpinBox跟QSpinBox类似,只是多了一个decimal. 
- 1.1大数据平台架构及Hadoop生态圈
			1.硬件架构实例 2.软件架构实例 3.数据流通用概念模型 a.数据源(互联网.物联网.企业数据):App.Device.Site b.数据收集(ETL.提取.转换.加载):Flume.Kafka.S ... 
- 1、写在开头的话——Tinking in Java 绪论之我见
			新兵道歉!版式不懂,技术若有错误,请指正,或发我邮箱1300431700@qq.com 不胜感激! 本文力图通过文章总结的形式,阐述自己的观点,迫使自己思考书中精髓,即使跟技术无关! 正文开始! “上 ... 
- Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined)
			C 模拟 题意:给的是一个矩形,然后√2 的速度走,如果走到边上就正常反射,走到角上,暂停反射,我们知道要不循环要不暂停,记录走到的点最短时间 /*************************** ... 
- maven 控制台 打包
			maven打包方法1.打开cmd,进入到项目的根目录2.执行命令:mvn clean package等待结束.结束后到目录的target子目录中找jar文件即可 
