2016北京集训 小Q与进位制
题目大意
一个数每一位进制不同,已知每一位的进制,求该数的十进制表达。
显然有
$$Ans=\sum\limits_{i=0}^{n-1}a_i \prod\limits_{j=0}^{i-1}base_j$$
若不考虑高精度则线性复杂度内由低位向高位递推即可,但考虑高精度的话即使压位也会$TLE$。
采用分治$+FFT$加速运算的方法。
分别求出第$1$至第$\frac n2$位和第$\frac n2+1$至第$n$位的答案,顺便求出$\prod\limits_{i=0}^{\frac n2}base_i$。
简单的两数相加提取公因数即可。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define M 370020
#define MAXN 1000
#define MLEN 10000000ll
const double PI=acos(-1);
using namespace std;
LL read(){
LL nm=0,fh=1; char cw=getchar();
for(;!isdigit(cw);cw=getchar()) if(cw=='-') fh=-fh;
for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
return nm*fh;
}
void write(LL x){if(x>9) write(x/10);putchar(x%10+'0');}
struct comp{
double r,d;
comp(){r=d=0;}
comp(double _r,double _d){r=_r,d=_d;}
comp operator+ (const comp & ot)const{return comp(r+ot.r,d+ot.d);}
comp operator- (const comp & ot)const{return comp(r-ot.r,d-ot.d);}
comp operator* (const comp & ot)const{return comp(r*ot.r-d*ot.d,r*ot.d+d*ot.r);}
}tt1[M],tt2[M];
int od[M],lg[M];
void FFT(comp *x,int len,double kd){
for(int i=0;i<len;i++) if(i<od[i]) swap(x[i],x[od[i]]);
for(LL tt=1;tt<len;tt<<=1){
comp unit(cos(PI*kd/(tt*1.0)),sin(PI*kd/(tt*1.0))),now;
for(LL pos,st=0;st<len;st+=(tt<<1)){
for(now=comp(1.0,0.0),pos=st;pos<st+tt;pos++,now=now*unit){
comp t1=x[pos],t2=now*x[pos+tt]; x[pos]=t1+t2,x[pos+tt]=t1-t2;
}
}
}
if(kd<0.0){for(LL i=0;i<len;i++) x[i].r/=(len*1.0);}
}
void opt(LL *x,LL len){
for(len--,write(x[len]);len--;){
if(x[len]<100) putchar('0');
if(x[len]<10) putchar('0');
write(x[len]);
}
putchar('\n');
}
LL mul(LL *x,LL *T1,LL *T2,LL n1,LL n2){
LL len=(1ll<<lg[n1+n2]),N=n1+n2-1; x[N]=x[N+1]=0;
if(n1+n2<=1024){
for(int i=0;i<=n1+n2+2;i++) x[i]=0ll;
for(int i=0;i<n1;i++) for(int j=0;j<n2;j++) x[i+j]+=T1[i]*T2[j];
}
else{
for(int i=1;i<len;i++) od[i]=(od[i>>1]>>1)|((i&1)<<(lg[len]-2));
for(int i=0;i<n1;i++) tt1[i]=comp(T1[i],0);
for(int i=0;i<n2;i++) tt2[i]=comp(T2[i],0);
for(int i=n1;i<len;i++) tt1[i]=comp(0,0);
for(int i=n2;i<len;i++) tt2[i]=comp(0,0);
FFT(tt1,len,1.0),FFT(tt2,len,1.0);
for(int i=0;i<len;i++) tt1[i]=tt1[i]*tt2[i]; FFT(tt1,len,-1.0);
for(int i=0;i<len;i++) x[i]=floor(tt1[i].r+0.5);
}
for(int i=0;i<N;i++) x[i+1]+=x[i]/MAXN,x[i]%=MAXN;
while(x[N]>0) N++,x[N]=x[N-1]/MAXN,x[N-1]%=MAXN; return N;
}
LL add(LL *x,LL *x1,LL *x2,LL n1,LL n2){
if(n1>n2) return add(x,x2,x1,n2,n1);
LL N=n2; x[N]=x[N+1]=0;
for(LL i=0;i<N;i++) x[i]=x2[i]+(i>=n1?0:x1[i]);
for(LL i=0;i<N;i++) x[i+1]+=x[i]/MAXN,x[i]%=MAXN;
while(x[N]) N++,x[N]=x[N-1]/MAXN,x[N-1]%=MAXN; return N;
}
LL n,m,Len,Bs[M],a[M],X[M],A[18][M],B[18][M],AA[18][M],BB[18][M];
LL merge(LL l,LL r,LL kd,LL *x,LL *xx){
if(r==l){
LL rm=MLEN+1; x[0]=a[l],xx[0]=Bs[l];
if(x[0]>=MAXN) x[1]=x[0]/MAXN,x[0]%=MAXN,rm+=MLEN;
if(xx[0]>=MAXN) xx[1]=xx[0]/MAXN,xx[0]%=MAXN,rm++;
if(x[1]>=MAXN) x[2]=x[1]/MAXN,x[1]%=MAXN,rm+=MLEN;
if(xx[1]>=MAXN) xx[2]=xx[1]/MAXN,xx[1]%=MAXN,rm++;
return rm;
}
LL La,lenl=merge(l,((r+l)>>1),kd+1,A[kd+1],AA[kd+1]),la,lb; la=lenl/MLEN,lb=lenl%MLEN;
LL Lb,lenr=merge(((r+l)>>1)+1,r,kd+1,B[kd+1],BB[kd+1]),ra,rb; ra=lenr/MLEN,rb=lenr%MLEN;
La=mul(X,AA[kd+1],B[kd+1],lb,ra),La=add(x,A[kd+1],X,la,La);
if(kd) Lb=mul(xx,AA[kd+1],BB[kd+1],lb,rb); return La*MLEN+Lb;
}
int main(){
n=read(),lg[0]=-1,Bs[0]=1;
for(int i=0;i<M;i++) lg[i]=lg[i>>1]+1;
for(int i=0;i<n;i++) Bs[i]=read();
for(int i=0;i<n;i++) a[i]=read();
n=merge(0,n-1,0,A[0],AA[0]),n/=MLEN,opt(A[0],n);return 0;
}
2016北京集训 小Q与进位制的更多相关文章
- 【XSY1529】小Q与进位制 分治 FFT
题目大意 小Q发明了一种进位制,每一位的变化范围是\(0\)~\(b_i-1\),给你一个这种进位制下的整数\(a\),问你有多少非负整数小于\(a\).结果以十进制表示. \(n\leq 1 ...
- (2016北京集训十)【xsy1529】小Q与进位制 - 分治FFT
题意很简单,就是求这个数... 其实场上我想出了分治fft的正解...然而不会打...然后打了个暴力fft挂了... 没啥好讲的,这题很恶心,卡常卡精度还爆int,要各种优化,有些dalao写的很复杂 ...
- (2016北京集训十)【xsy1528】azelso - 概率期望dp
北京集训的题都是好题啊~~(于是我爆0了) 注意到一个重要的性质就是期望是线性的,也就是说每一段的期望步数可以直接加起来,那么dp求出每一段的期望就行了... 设$f_i$表示从$i$出发不回到$i$ ...
- (2016北京集训十)【xsy1530】小Q与内存
一道很有意思的神题~ 暴力平衡树的复杂度很对(并不),但是$2^{30}$的空间一脸屎 这题的正解是一个类似线段树的数据结构,我觉得很有创新性Orz 首先可以想到一种暴力就是用一个点代表一个区间,然后 ...
- [2016北京集训测试赛5]小Q与内存-[线段树的神秘操作]
Description Solution 哇真的异常服气..线段树都可以搞合并和拆分的啊orzorz.神的世界我不懂 Code #include<iostream> #include< ...
- [2016北京集训试题14]股神小D-[LCT]
Description Solution 将(u,v,l,r)换为(1,u,v,l)和(2,u,v,r).进行排序(第4个数为第一关键字,第1个数为第二关键字).用LCT维护联通块的合并和断开.(维护 ...
- (2016北京集训十四)【xsy1556】股神小D - LCT
题解: 题解居然是LCT……受教了 把所有区间按照端点排序,动态维护目前有重叠的区间,用LCT维护即可. 代码: #include<algorithm> #include<iostr ...
- 2016北京集训测试赛(十四)Problem B: 股神小D
Solution 正解是一个\(\log\)的link-cut tree. 将一条边拆成两个事件, 按照事件排序, link-cut tree维护联通块大小即可. link-cut tree维护子树大 ...
- 2016北京集训测试赛(十四)Problem A: 股神小L
Solution 考虑怎么卖最赚钱: 肯定是只卖不买啊(笑) 虽然说上面的想法很扯淡, 但它确实能给我们提供一种思路, 我们能不买就不买; 要买的时候就买最便宜的. 我们用一个优先队列来维护股票的价格 ...
随机推荐
- pycharm的安装和破解
前提: 为了学习爬虫,单独下载了一个pycharm编辑器,所以就有了这篇文章,和PHPstorm的安装和破解及其类似, 如有想了解PHPstorm的安装破解可参考我的另一篇博文:http://www. ...
- Python的Django框架中的Context使用
Python的Django框架中的Context使用 近期整理些Python方面的知识,一旦你创建一个 Template 对象,你能够用 context 来传递数据给它. 一个context是一系列变 ...
- double,long double及各变量数组内存开销
IEEE754浮点数的表示方法.C语言里对float类型数据的表示范围为-3.4*10^38-+3.4*10^38.double为-1.7*10^-308~1.7*10^308,long double ...
- 【BZOJ2407/4398】探险/福慧双修 最短路建模
[BZOJ2407]探险 Description 探险家小T好高兴!X国要举办一次溶洞探险比赛,获奖者将得到丰厚奖品哦!小T虽然对奖品不感兴趣,但是这个大振名声的机会当然不能错过! 比赛即将开始,工作 ...
- EasyDSS流媒体解决方案实现的实时数据统计报表、视频文件上传、点播、分享、集成代码等功能
之前的EasyDSS作为rtmp流媒体服务器自从推出就备受用户好评,随着用户的需求的变更产品自身的发展是必须的: 为了更好的用户体验和和功能的完善,我们在EasyDSS的基础上增添了服务器硬件数据报表 ...
- 物理cpu和逻辑cpu
1 物理cpu 插槽里面实际插入的cpu的个数. 通过不重复的physical id可以获取实际的物理cpu的个数. 2 逻辑cpu cat /proc/info processor 1 proces ...
- Linux 3 -grep
七. grep家族: 1. grep退出状态: 0: 表示成功: 1: 表示在所提供的文件无法找到匹配的pattern: 2: 表示参数中提供的文件不存在. 见如下示例: /> grep 'ro ...
- 让input表单输入框不记录输入过信息的方法
有过表单设计经验的朋友肯定知道,当我们在浏览器中输入表单信息的时候,往往input文本输入框会记录下之前提交表单的信息,以后每次只要双击input文本输入框就会出现之前输入的文本,这样有时会觉得比较方 ...
- 培训笔记——Linux基本命令
在介绍命令之前,更重要的要先介绍一下快速输入命令的方法. 如果你能记住一些常用命令,毫无疑问,通过命令的操作方式比通过鼠标的操作方式要快. 但是有一些命令或是命令用到的参数如文件名特别复杂特别长,这时 ...
- hadoop自带例子SecondarySort源码分析MapReduce原理
这里分析MapReduce原理并没用WordCount,目前没用过hadoop也没接触过大数据,感觉,只是感觉,在项目中,如果真的用到了MapReduce那待排序的肯定会更加实用. 先贴上源码 pac ...