列表

详情


NC207489. 多项式

描述

小C是CUGACM的一名萌新,从其他的学长哪里了解到,ACM比赛中数学知识是很重要的,所以他花了一段时间学习了一些数学知识。首先他研究了一下多项式展开,小C在高中学到了二项式展开:

他在想如果括号里面是一个多项式该怎么展开呢?他想了想感觉好像有点复杂,然后简化了一下这个问题,考虑:

同时他的队友告诉他了一中神奇的数:"数",这种数被定义为:
.
(是莫比乌斯函数,的绝对值),
现在他让这个多项式里面的是神奇的""数,他现在想知道,对于任意的 ,a_k是多少呢?


输入描述

输入一行,每行三个数,

输出描述

输出题目中描述的a_k。由于a_k可能比较大,所以你只需要输出a_k取模之后的结果。

示例1

输入:

1 1 3

输出:

2

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 861ms, 内存消耗: 660K, 提交时间: 2020-07-20 22:55:16

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=2e5+5;
int prim[maxn/5],prime_n;
bool is_pr[maxn]={1,1};
void prime(){
    for(int i=2;i<maxn;i++){
        if(!is_pr[i])prim[prime_n++]=i;//ûÓÐɸµôµÄΪËØÊý
        for(int j=0;j<prime_n&&i*prim[j]<maxn;j++){
            is_pr[prim[j]*i]=1;//ɸµô
            if(i%prim[j]==0)break;//ºóÃæµÄÊý×îСÒòÊýÒ»¶¨Ð¡ÓÚµÈÓÚprim[j]
        }
    }
}
LL n,k,p,ans;
LL qmul(LL a,LL b){
	LL ans=0;
	while(b){
		if(b&1)ans=(ans+a)%p;
		a=(a<<1)%p,b>>=1;
	}
	return ans;
}
LL qpow(LL a,LL b){
	LL ans=1;
	while(b){
		if(b&1)ans=qmul(ans,a);
		a=qmul(a,a),b>>=1;
	}
	return ans;
}
int calc(int a,int b,int x){
	int ans=0,c=a-b;
	while(a)ans+=(a/=x);
	while(b)ans-=(b/=x);
	while(c)ans-=(c/=x);
	return ans;
}
void work(){
	LL ans=1;n<<=1;
	for(int i=0;i<prime_n;i++){
		ans=qmul(ans,qpow(prim[i],calc(n,k,prim[i])));
	}
	printf("%lld\n",ans);
}
int main(){
	prime();
	while(~scanf("%lld%lld%lld",&n,&k,&p))work();
	return 0;
} 

上一题