• 【AtCoder】P137F Folynomial Consruction


    数论

    由于p是素数,考虑到费马小定理:

    [a^{p-1} equiv 1 (mod p) ]

    而再观察,函数(f(x))要求的值都是0或1
    那么,将费马小定理变一下:

    [(x-i)^{p-1} equiv 1 (mod p)(x eq i) ]

    [(x-i)^{p-1} equiv 0 (mod p)(x = i) ]

    我们定义一个p-1次多项式(g(x)=b_0+b_1 imes x+b_2 imes x^2+...+b_{p-1} imes x^{p-1}),且该多项式初始值为0
    那么,对于一个(A_i),若(A_i=1),我们可以在(g(x))中加上(1-(x-i)^{p-1})。因为根据上述式子,我们可以得知在模p下,当且仅当x=i时,(1-(x-i)^{p-1})的值才为1,否则都为0。也就是说,(1-(x-i)^{p-1})只会影响x=i的情况(将其值变为1)。
    然后在多项式展开就行了。
    代码(注意负数取模):

        #include<bits/stdc++.h>
        using namespace std;
        int n,A[10100],cnt[10010],ans[10100],C[3000][3000];
        void init(){
        	C[0][0]=1;
        	for(int i=1;i<=n;i++){
        		C[i][0]=1;
        		for(int j=1;j<=i;j++){
        			C[i][j]=(C[i-1][j]+C[i-1][j-1])%n;
        		}
        	}
        }
        int main(){
        	scanf("%d",&n);
        	init();
        	for(int i=0;i<n;i++)scanf("%d",&A[i]);
        	for(int i=0;i<n;i++){
        		if(A[i]==1)cnt[i]++,ans[0]++;
        	}
        	for(int i=0;i<n;i++){
        		if(cnt[i]==0)continue;
        		for(int j=0,po=1;j<n;j++){
        			int res=C[n-1][j]*po;
        			res%=n;
        			if(res<0){
        				int tmp=abs(res);
        				res=(n-tmp%n)%n;
        			}
        			else res=res%n;
        			ans[n-1-j]=(ans[n-1-j]+n-res)%n;
        			po=po*(-i);
        			if(po<0){
        				int tmp=abs(po);
        				po=(n-tmp%n)%n;
        			}
        			else po=po%n;
        		}
        	}
        	for(int i=0;i<n;i++)printf("%d ",ans[i]);
        	return 0;
        }
    
  • 相关阅读:
    BZOJ 3991 set维护dfs序
    BZOJ 4547 矩阵快速幂
    WERTYU | TEX Quotes
    高精度运算
    最大公约数和最小公倍数
    老鼠的旅行
    数据交换
    1136 A Delayed Palindrome
    1137 Final Grading
    1138 Postorder Traversal
  • 原文地址:https://www.cnblogs.com/SillyTieT/p/11333969.html
Copyright © 2020-2023  润新知