COGS2294 释迦

传送门

就是传说中的任意模数卷积嘛……有三模数NTT和拆系数FFT等做法,我比较懒不想动脑子,就用了三模数NTT的做法……

卷积之后每个数可以达到$10^{23}$左右的级别,直接long double或者__float128都会炸精度(而且__float128炸得更惨……好像是转换的时候掉精度太多……)。而这个模数又不能NTT(首先这就不是个质数……),因此直接搞是行不通的。

我们可以选三个满足NTT性质并且乘起来$>10^{23}$的模数分别NTT,最后中国剩余定理合并。但注意到$10^{23}>2^{64}$,因此直接合并会炸long long,所以我们就需要一些tricky的办法来合并。

我们得到的是这样的三个同余式:

\begin{equation}Ans\equiv a_1(\mod m_1)\\Ans\equiv a_2(\mod m_2)\\Ans\equiv a_3(\mod m_3)\end{equation}

先用中国剩余定理合并前两个同余式,得到

\begin{equation}Ans\equiv A(\mod M)\\Ans\equiv a_3(\mod m_3)\end{equation}

不妨设

\begin{equation}Ans=kM+A=xm_3+a_3\end{equation}

我们可以在$\mod m_3$的意义下求解k的值,那么有

\begin{equation}kM\equiv a_3-A(\mod m_3)\end{equation}

(因为是在$\mod m_3$的意义下,所以$xm_3$被消掉了)

也就是说

\begin{equation}k\equiv (a_3-A)M^{-1}(\mod m_3)\end{equation}

求出$k$之后代入$Ans=kM+A$,这次只要在$\mod 23333333$的意义下算出$Ans$的值即可。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn=262200,m1=998244353,m2=1004535809,m3=469762049,g=3,Mod=23333333;
 6 const long long M=(long long)m1*m2;
 7 void NTT(int*,int,int,int);
 8 int China(int,int,int);
 9 int qpow(int,int,int);
10 long long mul(long long,long long,long long);
11 int n,N=1,A[maxn],B[maxn],C[maxn],D[maxn],a[3][maxn];
12 int main(){
13     freopen("annona_squamosa.in","r",stdin);
14     freopen("annona_squamosa.out","w",stdout);
15     scanf("%d",&n);
16     while(N<(n<<1))N<<=1;
17     for(int i=0;i<n;i++)scanf("%d",&A[i]);
18     for(int i=0;i<n;i++)scanf("%d",&B[i]);
19     copy(A,A+N,C);
20     copy(B,B+N,D);
21     NTT(C,N,1,m1);
22     NTT(D,N,1,m1);
23     for(int i=0;i<N;i++)a[0][i]=(long long)C[i]*D[i]%m1;
24     NTT(a[0],N,-1,m1);
25     copy(A,A+N,C);
26     copy(B,B+N,D);
27     NTT(C,N,1,m2);
28     NTT(D,N,1,m2);
29     for(int i=0;i<N;i++)a[1][i]=(long long)C[i]*D[i]%m2;
30     NTT(a[1],N,-1,m2);
31     copy(A,A+N,C);
32     copy(B,B+N,D);
33     NTT(C,N,1,m3);
34     NTT(D,N,1,m3);
35     for(int i=0;i<N;i++)a[2][i]=(long long)C[i]*D[i]%m3;
36     NTT(a[2],N,-1,m3);
37     for(int i=0;i<n;i++)printf("%d\n",China(a[0][i],a[1][i],a[2][i]));
38     return 0;
39 }
40 void NTT(int *A,int n,int tp,int p){
41     for(int i=0;i<n;i++)A[i]%=p;
42     for(int i=1,j=0,k;i<n-1;i++){
43         k=n;
44         do j^=(k>>=1);while(j<k);
45         if(i<j)swap(A[i],A[j]);
46     }
47     for(int k=2;k<=n;k<<=1){
48         int wn=qpow(g,(tp>0?(p-1)/k:(p-1)/k*(long long)(p-2)%(p-1)),p);
49         for(int i=0;i<n;i+=k){
50             int w=1;
51             for(int j=0;j<(k>>1);j++,w=(long long)w*wn%p){
52                 int a=A[i+j],b=(long long)w*A[i+j+(k>>1)]%p;
53                 A[i+j]=(a+b)%p;
54                 A[i+j+(k>>1)]=(a-b+p)%p;
55             }
56         }
57     }
58     if(tp<0){
59         int inv=qpow(n,p-2,p);
60         for(int i=0;i<n;i++)A[i]=(long long)A[i]*inv%p;
61     }
62 }
63 int China(int a1,int a2,int a3){
64     long long A=(mul((long long)a1*m2%M,qpow(m2%m1,m1-2,m1),M)+mul((long long)a2*m1%M,qpow(m1%m2,m2-2,m2),M))%M,k=((a3-A)%m3+m3)%m3*qpow(M%m3,m3-2,m3)%m3;
65     return ((k%Mod)*(M%Mod)%Mod+A%Mod)%Mod;
66 }
67 int qpow(int a,int b,int p){
68     int ans=1;
69     for(;b;b>>=1,a=(long long)a*a%p)if(b&1)ans=(long long)ans*a%p;
70     return ans;
71 }
72 long long mul(long long a,long long b,long long p){
73     a%=p;b%=p;
74     return ((a*b-(long long)((long long)((long double)a/p*b+1e-3)*p))%p+p)%p;
75 }

时间: 2025-01-17 16:56:24

COGS2294 释迦的相关文章

SqlSever基础 convert 将类型为字符的一列转成Int类型后进行排序

镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ 1 base code 1 use master 2 drop database helloworld 3 4 --创建一个数据库 5 create database helloworld 6 7 --用helloworld1这个数据库 8 use helloworld 9 10 --创建一个表格

SqlSever基础 union 将得到的横表变为纵表

镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ 1 base code 1 use master 2 drop database helloworld 3 4 --创建一个数据库 5 create database helloworld 6 7 --用helloworld1这个数据库 8 use helloworld 9 10 --创建一个表格

《增广贤文》以及解释

昔时贤文,诲汝谆谆. 集韵增广,多见多闻. 观今宜鉴古,无古不成今. [解释]用以前圣贤们的言论,来谆谆教诲你.广泛搜集押韵的文字汇编成“增广”,使你见多识广.应该借鉴古人的经验教训,来指导今天的行为,因为今天是古代的延续. 知己知彼,将心比心. [解释]知道自己怎么想的,也应该知道别人是怎样想的,所以要用自己的心,体谅别人的心,设身处地为别人着想. 酒逢知己饮,诗向会人吟. 相识满天下,知心能几人. [解释]酒要和了解自己的人一起喝,诗要与懂得它的人一起吟.认识的人可以很多,但真正了解,并达到

C#并行编程 z

目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 C#并行编程-线程同步原语 C#并行编程-PLINQ:声明式数据并行 背景 基于任务的程序设计.命令式数据并行和任务并行都要求能够支持并发更新的数组.列表和集合. 在.NET Framework 4 以前,为了让共享的数组.列表和集合能够被多个线程更新,需要添加复杂的代码来同步这些更新操作. 如您需要编写一个并行循环,这个循环以无序的方式向一个共享集合中添加元素,那么必须加入一个同步机制

悟透JavaScript

From: 李战,http://www.cnblogs.com/leadzen/archive/2008/02/25/1073404.html 引子 编程世界里只存在两种基本元素,一个是数据,一个是代码.编程世界就是在数据和代码千丝万缕的纠缠中呈现出无限的生机和活力. 数据天生就是文静的,总想保持自己固有的本色:而代码却天生活泼,总想改变这个世界.    你看,数据代码间的关系与物质能量间的关系有着惊人的相似.数据也是有惯性的,如果没有代码来施加外力,她总保持自己原来的状态.而代码就象能量,他存

楞严经白话——14.10.10

楞严经 大佛顶如来密因修证了义诸菩萨万行首 楞严经卷一 唐朝中天竺国(印度)沙门(出家人)般剌密谛 主译 乌苌国(北印度)沙门(出家人)弥伽释迦 译语 菩萨戒弟子 前正议大夫 同中书门下 平章事 清河县人 房融 执笔记录 (楞严经,原藏于龙宫,胜龙菩萨到龙宫说法,见龙藏中有此经,披阅之下,叹为希有,遂默诵而出,录呈印度国王,国王视其为国宝,严禁外流.般剌密 谛尊者,弘法愿深,两次冒险,思送中国以求宏扬,不幸皆为关卡查禁.尊者乃费数年时间,以蝇头小字书于腊纸之上,剖膊藏于肉中,方得过关航海而来,于

楞严经——14.10.10

楞严经原文 大佛顶如来密因修证了义 般剌密帝译 卷一 如是我闻.一时.佛在室罗筏城.祇桓精舍.与大比丘众.千二百五十人俱.皆是无漏大阿罗汉.佛子住持.善超诸有.能于国土.成就威仪.从佛转轮.妙堪 遗嘱.严净毗尼.弘范三界.应身无量.度脱众生.拔济未来.越诸尘累.其名曰.大智舍利弗.摩诃目犍连.摩诃拘絺罗.富楼那弥多罗尼子.须菩提.优波尼沙 陀等.而为上首.复有无量辟支无学.并其初心.同来佛所.嘱诸比丘.休夏自恣.十方菩萨.咨决心疑.钦奉慈严.将求密义.即时.如来敷座宴安.为诸会中. 宣示深奥.法

Sql Server 调用DLL

原文:Sql Server 调用DLL 背景 在处理数据或者分析数据时,我们常常需要加入一定的逻辑,该些处理逻辑有些sql是可以支持,有些逻辑SQL则无能为力,在这种情况下,大多数人都会编写相关的程序来处理成自己想要的数据,但每次处理相同逻辑时,都需要运行一次程序非常麻烦. 案例 IE地址栏上的地址在记入日志表中时,其数据是通过编码的,如果我们想要看到明文,则需要相应的解码,可以用SQL语句来实现,如: 摘自:http://blog.csdn.net/ruijc/article/details/

Python3基础 for循环 遍历并输出一个字符串的列表

镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ 1 code 1 name=['燃灯古佛','释迦摩尼佛','弥勒佛'] 2 3 for item in name: 4 print(item) 2 show ------------------------------------------博文的精髓,在技术部分,更在镇场一诗.Python是优