Codeforces 1103 E. Radix sum
神题。
题意:给定一个长度为\(10^5\)的幂级数\(a\),将卷积的下标运算定义为十进制下的不进位加法,求\(a^k\)模\(2^{58}\)的结果。\(k\leq 10^9\)。
题解:
考虑在复数域下的做法,那么根据卷积的复合只要将\(a\)看作是\(5\)维的、每一维长度为\(10\)的幂级数,对每一维做长度为\(10\)的循环卷积即可。然而现在是取模甚至不是对质数取模。那么我们需要关心两个问题:
\(1\)、如何解决求逆元的问题。
\(2\)、如何在模意义下找到\(10\)次单位根,即\(\omega_{10}\)。
第一个问题比较好解决,考虑在计算过程中,唯一需要做除法的时候就是在\(\rm IDFT\)之后将所有数字除以\(10^5\),那么考虑到\(5\)的逆元是存在的,直接计算即可。现在我们的问题是要除以\(2^5\)。那么我们显然可以通过\(\text{unsigned long long}\)求得\(x*2^5\bmod 2^{64}\)的结果,考虑如何求出\(x\bmod 2^{58}\)。我们知道这样一个事实:
如果\(x*2^5\bmod 2^{64}\)为\(y\),那么\(x*2^4\bmod 2^{64}\)只可能为\(\frac{y}{2}\)或者\(\frac{y}{2}+2^{63}\),发现两者在模\(2^{63}\)意义下显然是等价的,于是\(\frac{y}{2}\)就是\(x*2^4\bmod 2^{63}\),以此类推,\(\frac{y}{32}\)就是\(x\bmod x^{59}\),虽然不知道为什么出题人要开\(2^{58}\),但是我们只要再取模一下就可以得到我们想要的结果了。
现在的问题是在模意义下找到\(\omega_{10}\)。这个问题有些困难,但是我们可以发现\(\omega_{10}^5\)在模\(2^{64}\)意义下是存在的,即\(-1\)。于是我们只要知道\(\omega_{10}^2=\omega_{5}\),就可以计算出\(\omega_{10}\)。
一个比较简单的解决办法是,我们设\(x=\omega_5\),将普通的数字转化为形式幂级数。这样做虽然可以,但是在相乘的过程中显然次数会非常爆炸。但是我们同时可以注意到一个简单的事实:\(\omega_5^5=1\),即\(x^5-1=0\),也就是说我们的形式幂级数中\(x^5-1\)的倍数值为\(0\),因此其实都是不必要的。于是我们可以将形式幂级数放在模\(x^5-1\)的多项式环下,这样我们的次数界可以保持在\(5\)并且依然保证这么做的正确性。
同时我们可以发现,\(x=1\)时\(x^5-1\)的值也为\(0\),这其实是不必要的。于是我们还可以将模多项式改为\(\frac{x^5-1}{x-1}=1+x+x^2+x^3+x^4\),可以发现这个多项式的根只有\(\omega_5,\omega_5^2,\omega_5^3,\omega_5^4\)这\(4\)个无理数,我们接下来的解法会用到这一点。
于是我们将模\(1+x+x^2+x^3+x^4\)的多项式环作为一种数据类型,直接进行\(\rm DFT\)后计算每一项的快速幂,再进行\(\rm IDFT\)即可。现在我们还有最后一个疑问是得到的每一个答案中\(x\)、\(x^2\)或者\(x^3\)的系数会不会非\(0\),如果出现这种情况似乎比较棘手。但是接下来我们可以证明这三项的系数一定是\(0\)。
由\(\rm DFT\)的正确性可知,我们计算得到的答案和\(n^2\)暴力的答案应该是一样的。而\(n^2\)暴力的答案都是整数,因此我们得到的答案实际上也必定是整数。也就是说,假如某个答案\(x\)、\(x^2\)或者\(x^3\)的系数有至少一个非\(0\),那我们设它们分别为\(a_1,a_2,a_3\),于是我们可以得知\(a_1*x+a_2*x^2+a_3*x^3\)一定是一个整数,设其为\(y\),那么也就是说我们可以满足方程\(-y+a_1*x+a_2*x^2+a_3*x^3=0\),将其因式分解为\(k*\prod_i(x-r_i)\)的形式,其中\(k\)是一个非\(0\)整数,\(r_i\)是这个方程的某个根,可以得知其次高项的系数为\(-k*(\sum_i r_i)\),同时由前面的结论可知根中至少包含\(\omega_5,\omega_5^2,\omega_5^3,\omega_5^4\)中的\(1\)个,同时受次数的限制最多包含\(3\)个。可以发现无论怎样选取,它们相加的结果也必然是无理数,于是可证明该方程不存在。于是\(a_1,a_2,a_3\)都为\(0\)。
代码:
#include<cstdio>
#include<cstring>
typedef unsigned long long ull;
const ull mod=1ll<<58;
const ull inv5=14757395258967641293ull;
struct complex
{
ull a[4];
complex(ull x=0)
{
a[0]=x;a[1]=a[2]=a[3]=0;
return;
}
inline complex operator+(const complex &th)
{
complex res;
res.a[0]=a[0]+th.a[0];
res.a[1]=a[1]+th.a[1];
res.a[2]=a[2]+th.a[2];
res.a[3]=a[3]+th.a[3];
return res;
}
inline complex operator-(const complex &th)
{
complex res;
res.a[0]=a[0]-th.a[0];
res.a[1]=a[1]-th.a[1];
res.a[2]=a[2]-th.a[2];
res.a[3]=a[3]-th.a[3];
return res;
}
inline complex operator*(const complex &th)
{
ull b[7];
b[0]=a[0]*th.a[0];
b[1]=a[0]*th.a[1]+a[1]*th.a[0];
b[2]=a[0]*th.a[2]+a[1]*th.a[1]+a[2]*th.a[0];
b[3]=a[0]*th.a[3]+a[1]*th.a[2]+a[2]*th.a[1]+a[3]*th.a[0];
b[4]=a[1]*th.a[3]+a[2]*th.a[2]+a[3]*th.a[1];
b[5]=a[2]*th.a[3]+a[3]*th.a[2];
b[6]=a[3]*th.a[3];
b[5]-=b[6];b[4]-=b[6];b[3]-=b[6];b[2]-=b[6];b[6]=0;
b[4]-=b[5];b[3]-=b[5];b[2]-=b[5];b[1]-=b[5];b[5]=0;
b[3]-=b[4];b[2]-=b[4];b[1]-=b[4];b[0]-=b[4];b[4]=0;
complex res;
res.a[0]=b[0];res.a[1]=b[1];res.a[2]=b[2];res.a[3]=b[3];
return res;
}
}w10[10];
inline complex qpow(complex a,int b)
{
complex res=w10[0];
for(;b;a=a*a,b>>=1)
if(b&1)
res=res*a;
return res;
}
inline void init()
{
register int i;
w10[0].a[0]=1;w10[1].a[3]=-1;
for(i=2;i<10;i++)
w10[i]=w10[i-1]*w10[1];
return;
}
const int N=1e5+5;
const int pow10[]={1,10,100,1000,10000,100000,1000000};
int n;
complex a[N],b[10];
inline void hddft()
{
register int d,i,j,k;
for(d=0;d<5;d++)
{
for(i=0;i<100000;i++)
if((i/pow10[d])%10==0)
{
memset(b,0,sizeof(b));
for(j=0;j<10;j++)
for(k=0;k<10;k++)
b[j]=b[j]+a[i+k*pow10[d]]*w10[j*k%10];
for(j=0;j<10;j++)
a[i+j*pow10[d]]=b[j];
}
}
return;
}
inline void hdidft()
{
register int d,i,j,k;
for(d=0;d<5;d++)
{
for(i=0;i<100000;i++)
if((i/pow10[d])%10==0)
{
memset(b,0,sizeof(b));
for(j=0;j<10;j++)
for(k=0;k<10;k++)
b[j]=b[j]+a[i+k*pow10[d]]*w10[(10-j*k%10)%10];
for(j=0;j<10;j++)
a[i+j*pow10[d]]=b[j];
}
}
ull w=inv5*inv5*inv5*inv5*inv5;
for(i=0;i<100000;i++)
a[i]=a[i]*w;
return;
}
signed main()
{
int x;
register int i;
init();
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&x),a[x].a[0]++;
hddft();
for(i=0;i<100000;i++)
a[i]=qpow(a[i],n);
hdidft();
for(i=0;i<n;i++)
printf("%llu\n",(a[i].a[0]/32)%mod);
return 0;
}
Codeforces 1103 E. Radix sum的更多相关文章
- Codeforces 1103 C. Johnny Solving
Codeforces 1103 C. Johnny Solving 题目大意: 有一张 \(n\) 个点 \(m\) 条边的简单无向图,每个点的度数至少为 \(3\) ,你需要构造出两种情况之一 一条 ...
- Codeforces 963 A. Alternating Sum(快速幂,逆元)
Codeforces 963 A. Alternating Sum 题目大意:给出一组长度为n+1且元素为1或者-1的数组S(0~n),数组每k个元素为一周期,保证n+1可以被k整除.给a和b,求对1 ...
- [Codeforces 280D]k-Maximum Subsequence Sum(线段树)
[Codeforces 280D]k-Maximum Subsequence Sum(线段树) 题面 给出一个序列,序列里面的数有正有负,有两种操作 1.单点修改 2.区间查询,在区间中选出至多k个不 ...
- CodeForces 1103E. Radix sum
题目简述:对任意两个(正)十进制数$a = \overline{a_{k-1}\dots a_1a_0}$和$b = \overline{b_{k-1}\dots b_1b_0}$,定义其[十进制按位 ...
- Codeforces Educational Codeforces Round 5 E. Sum of Remainders 数学
E. Sum of Remainders 题目连接: http://www.codeforces.com/contest/616/problem/E Description The only line ...
- ●CodeForces 280D k-Maximum Subsequence Sum
题链: http://codeforces.com/problemset/problem/280/D 题解: 神题,巨恶心.(把原来的那个dp题升级为:序列带修 + 多次询问区间[l,r]内取不超过k ...
- Codeforces 280D k-Maximum Subsequence Sum [模拟费用流,线段树]
洛谷 Codeforces bzoj1,bzoj2 这可真是一道n倍经验题呢-- 思路 我首先想到了DP,然后矩阵,然后线段树,然后T飞-- 搜了题解之后发现是模拟费用流. 直接维护选k个子段时的最优 ...
- CodeForces 1060 B Maximum Sum of Digits
Maximum Sum of Digits You are given a positive integer n. Let S(x)S(x) be sum of digits in base 10 r ...
- Codeforces 622 F. The Sum of the k-th Powers
\(>Codeforces \space 622\ F. The\ Sum\ of\ the\ k-th\ Powers<\) 题目大意 : 给出 \(n, k\),求 \(\sum_{i ...
随机推荐
- http协议以及get和post请求
HTTP协议是网络传输信息的一种规范. 就好比两个人之间的交流,甲只会讲英语,乙只会说汉语,结果是他们必然无法开怀畅谈. HTTP协议也类 GET 请求获取 Request-URI 所标识的资源 ...
- 基于TDA4863-2的单级PFC反激LED电源设计与仿真
LED是一个非线性器件,正向电压的微小变化会引起电流的巨大变化:LED是一个半导体二极管,其伏安特性随温度变化而变化(-2mV/℃),假如温度升高,在恒压驱动下LED的电流会增加.长期超过额定电流工作 ...
- ASP.NET Core如何设置请求超时时间
如果一个请求在ASP.NET Core中运行太久,会导致请求超时,目前ASP.NET Core对请求超时的设置比较麻烦,本文列出目前收集到的一些方法,供大家参考. 部署ASP.NET Core到IIS ...
- 读取Excel的记录并导入SQL数据库
准备一下,近段时间,需要把Excel的数据导入数据库中. 引用命名空间: using System.Configuration; using System.Data; using System.Dat ...
- RabbmitMQ-工作队列及相关概念
工作队列-WorkQueue 实现功能: 将耗时的任务分发给多个工作者 设计思想: 避免直接去做一件资源密集型的任务,并且还得等它完成.因此将任务安排后再去做.将任务封装为一个消息,发到队列中.一个工 ...
- HNOI2018简要题解
HNOI2018简要题解 D1T1 寻宝游戏 题意 某大学每年都会有一次 Mystery Hunt 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为 ...
- 【SDOI2017】数字表格
题面 题解 这道题目还有一种比较有意思的解法. 定义一种运算\((\mathbf f\oplus\mathbf g)(x) = \prod\limits_{d\mid x}\mathbf f(d)^{ ...
- 在Ubuntu18.04下将应用程序添加到启动器
# 在启动器里面给应用程序添加一个快捷方式 在linux(ubuntu)平台下,很多小伙伴发现,自己去官网下载解压的软件不能自动添加到启动器,每次启动的时候需要再次进入软件目录输入命令,非常不方便.本 ...
- C_数据结构_链式二叉树
# include <stdio.h> # include <malloc.h> struct BTNode { int data; struct BTNode * pLchi ...
- Individual Project - Word frequency program——12061154Joy
Description&Requirement: http://www.cnblogs.com/jiel/p/3978727.html 项目时间估计 理解项目要求: 1h 构建项目逻辑: 1h ...