[cf1103E]Radix sum
类似于uoj272,即$B=10$的情况,然后有以下几个细节问题:
1.答案对$2^{58}$取模可以先使用自然溢出模$2^{64}$,最后对$2^{58}$取模即可
2.为了避免实数,令$\omega=\cos\frac{2\pi}{10}+\sin\frac{2\pi}{10}i$,初始每一个数必然是$\omega^{i}$,相乘也就是多项式乘法
根据$\omega^{10}=1$,可以将其幂次对10取模,即是一个9次多项式
又因为$\omega^{5}=-1$,因此$\omega^{i+5}=-\omega^{i}$,即可以将5-9次项都降为0-4次项
再根据$\omega^{4}-\omega^{3}+\omega^{2}-\omega^{1}+1=\frac{1+\omega^{5}}{1+\omega}=0$,可以将4次项降为0-3次项
接下来,考虑若最后1-3次项存在非0,由于最终结果是实数,因此这些次项的虚部带权和为0
其实部带权和一定可以用$\omega^{0}$来表示,也就是可以继续降幂,但事实上我们无法再找到可以降$\omega^{3}$的式子,因此最终必然只有$\omega^{0}$系数非0,即答案(严格地证明并不会证)
3.关于10在模$2^{64}$下不一定没有逆元,可以将10放在最外面除以$10^{5}$,之后由于2一定是可以直接除掉的(因为最终结果是整数),再求出5的逆元$inv$,乘上$inv^{5}$即可
时间复杂度为$o(4^{2}Bn+n\log_{2}n)$(这里$n=10^{5}$,不与数字数量区分)
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100005
4 #define M 5
5 #define B 10
6 #define ll long long
7 int n,m,x,base[N][M];
8 struct Complex{
9 unsigned ll a[4];
10 Complex(){
11 memset(a,0,sizeof(a));
12 }
13 Complex(int x){
14 memset(a,0,sizeof(a));
15 a[0]=x;
16 }
17 Complex(int x,int y){
18 memset(a,0,sizeof(a));
19 a[0]=x,a[1]=y;
20 }
21 Complex operator + (const Complex &k)const{
22 Complex o;
23 for(int i=0;i<4;i++)o.a[i]=a[i]+k.a[i];
24 return o;
25 }
26 Complex operator * (const Complex &k)const{
27 Complex o;
28 for(int i=0;i<4;i++)
29 for(int j=0;j<4;j++){
30 if (i+j<4)o.a[i+j]=o.a[i+j]+a[i]*k.a[j];
31 if (i+j==4){
32 unsigned ll s=a[i]*k.a[j];
33 o.a[0]-=s,o.a[1]+=s,o.a[2]-=s,o.a[3]+=s;
34 }
35 if (i+j>4)o.a[i+j-5]=o.a[i+j-5]-a[i]*k.a[j];
36 }
37 return o;
38 }
39 }inv,A[B][B],invA[B][B],a[N];
40 Complex pow(Complex n,ll m){
41 Complex s=n,ans=Complex(1);
42 while (m){
43 if (m&1)ans=ans*s;
44 s=s*s;
45 m>>=1;
46 }
47 return ans;
48 }
49 void DFT(Complex *a){
50 Complex aa[B];
51 for(int i=0,s=1;i<M;i++,s*=B)
52 for(int j=0;j<n;j++)
53 if (!base[j][i]){
54 for(int k=0;k<B;k++)aa[k]=Complex();
55 for(int k=0;k<B;k++)
56 for(int l=0;l<B;l++)aa[k]=aa[k]+a[j+l*s]*A[l][k];
57 for(int k=0;k<B;k++)a[j+k*s]=aa[k];
58 }
59 }
60 void IDFT(Complex *a){
61 Complex aa[B];
62 for(int i=0,s=1;i<M;i++,s*=B)
63 for(int j=0;j<n;j++)
64 if (!base[j][i]){
65 for(int k=0;k<B;k++)aa[k]=Complex();
66 for(int k=0;k<B;k++)
67 for(int l=0;l<B;l++)aa[k]=aa[k]+a[j+l*s]*invA[l][k];
68 for(int k=0;k<B;k++)a[j+k*s]=aa[k];
69 }
70 }
71 int main(){
72 n=1e5;
73 inv=pow(Complex(5),(1LL<<57)-1);
74 for(int i=0;i<n;i++){
75 base[i][0]=i%B;
76 for(int j=1;j<M;j++)base[i][j]=base[i/B][j-1];
77 }
78 for(int i=0;i<B;i++)
79 for(int j=0;j<B;j++){
80 A[i][j]=pow(Complex(0,1),i*j);
81 invA[i][j]=pow(Complex(0,1),B*B-i*j)*inv;
82 }
83 scanf("%d",&m);
84 for(int i=1;i<=m;i++){
85 scanf("%d",&x);
86 a[x]=a[x]+Complex(1);
87 }
88 DFT(a);
89 for(int i=0;i<n;i++)a[i]=pow(a[i],m);
90 IDFT(a);
91 for(int i=0;i<m;i++){
92 a[i].a[0]>>=M;
93 a[i].a[0]&=((1LL<<58)-1);
94 printf("%llu\n",a[i].a[0]);
95 }
96 }
[cf1103E]Radix sum的更多相关文章
- 题解 CF1103E Radix sum
题目传送门 题目大意 给出一个\(n\)个数的序列\(a_{1,2,..,n}\),可以选\(n\)次,每次可以选与上次选的相同的数,问对于\(\forall p\in[0,n-1]\)满足选出来的数 ...
- Codeforces 1103 E. Radix sum
题目链接 神题. 题意:给定一个长度为\(10^5\)的幂级数\(a\),将卷积的下标运算定义为十进制下的不进位加法,求\(a^k\)模\(2^{58}\)的结果.\(k\leq 10^9\). 题解 ...
- CodeForces 1103E. Radix sum
题目简述:对任意两个(正)十进制数$a = \overline{a_{k-1}\dots a_1a_0}$和$b = \overline{b_{k-1}\dots b_1b_0}$,定义其[十进制按位 ...
- $\text {FWT}$学习笔记
\(\text {FWT}\) 学习笔记 正常项的\(\text {FWT}\) 在\(\text {OI}\)中,我们经常会碰到这种问题: 给出一个长度为\(n\)的序列\(a_{1,2,...,n ...
- 1010 Radix
1010 Radix 注意点 如111 1 1 10类似情况下,若n为个位数,如果本身比另一个数小,则多少的进制都是没有用的(可能会造成空循环而超时),不过好像没有这么一个测试用例 进制应该比最少数据 ...
- 模拟实现C库的atoi、atof和itoa
1.C函数atoi atoi (表示 alphanumeric to integer)是把字符串转换成整型数的一个函数.广泛的应用在计算机程序和办公软件中.atoi( ) 函数会扫描参数 nptr字符 ...
- 模拟实现库函数的atoi、atof和itoa
1.函数atoi atoi (表示 alphanumeric to integer)是把字符串转换成整型数的一个函数.广泛的应用在计算机程序和办公软件中.atoi( ) 函数会扫描参数 nptr字符串 ...
- 字符串函数---itoa()函数具体解释及实现
itoa()函数 itoa():char *itoa( int value, char *string,int radix); 原型说明: value:欲转换的数据. string:目标字符串的地址. ...
- PAT 解题报告 1010. Radix (25)
1010. Radix (25) Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 11 ...
随机推荐
- Python小知识之对象的比较
好久不见 国庆回了趟老家,躺平了10天.作息时间基本和小学生差不多,8.9点就睡了, 那滋味别提多舒服了.时间也和小时候过得一样慢了...长时间不更新,还是不行滴,粉都快掉没了. 今天就结合日常生活的 ...
- redis学习笔记-02 list列表类型命令
一.lpush key value1 value2 value3 value4(命令将一个或多个值插入到列表头部. 如果 key 不存在,一个空列表会被创建并执行 LPUSH 操作) lpush k1 ...
- OO_JAVA_表达式求导
OO_JAVA_表达式求导_第一弹 ---------------------------------------------------表达式提取部分 词法分析 首先,每一个表达式内部都存在不可 ...
- Linux中检查字符串是否为合法IP地址的shell脚本
#!/bin/bash #判断IP地址是否为有效IP CHKECK_IP () { CHECK_STEP1=`echo $1 | awk -F"." '{print NF}'` i ...
- elasticsearch的dsl查询
测试es的dsl查询,准备数据,在插入数据的时候,如果index.type.mapping都没有,es会自动创建 一.数据的准备 curl -XPOST "http://192.168.99 ...
- 2019.03.27【GDOI2019】模拟 T3
题目大意 给出$n$, $p$, 求有多少长度为$n$的排列可以被分成三个上升子序列, 数量对$p$取模, 数据范围 $3 \leq n \leq 500$. 思路 首先让我们考虑如果有一个排列,如何 ...
- 大神教零基础入门如何快速高效的学习c语言开发
零基础如果更快更好的入门C语言,如何在枯燥的学习中找到属于自己的兴趣,如果把学习当成一种事务性的那以后的学习将会很难有更深入的进步,如果带着乐趣来完成学习那将越学越有意思这样才会让你有想要更深入学习的 ...
- 绘制PCB电路原理图的8种方法
1.选择集成电路,变压器,晶体管等组件,这些组件体积庞大,有许多引脚并在电路中起主要作用,然后从选定的参考引脚中抽取,以减少错误. 2.如果PCB上标有元件编号(如VD870,R330,C466等), ...
- 常用Java API: ArrayList(Vector) 和 LinkedList
摘要: 本文主要介绍ArrayList(Vector)和LinkedList的常用方法, 也就是动态数组和链表. ArrayList ArrayList 类可以实现可增长的对象数组. 构造方法 Arr ...
- spring-cloud-square开发实战(三种类型全覆盖)
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 前文<五分钟搞懂spring-clou ...