题目大意

​  小Q发明了一种进位制,每一位的变化范围是\(0\)~\(b_i-1\),给你一个这种进位制下的整数\(a\),问你有多少非负整数小于\(a\)。结果以十进制表示。

​  \(n\leq 120000,0\leq a_i<b_i\leq 1000000\)

题解

​  就是求这个数。

​  那没什么好说的,直接分治FFT

  处理左半边(低位)的\(c_1=\prod b_i\)和答案\(d_1\),右半边的\(c2,d2\)

​  那么\(c=c_1\times c_2,d=d_2\times c_1+d_1\)

​  时间复杂度:\(O(n\log^2 n)\)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
//typedef long double ld;
typedef double ld;
//const ld pi=3.1415926535897932384626433832L;
const ld pi=acos(ld(-1));
struct cp
{
ld x,y;
cp(ld _x=0,ld _y=0)
{
x=_x;
y=_y;
}
};
cp conj(cp &a){return cp(a.x,-a.y);}
cp operator +(cp &a,cp &b){return cp(a.x+b.x,a.y+b.y);}
cp operator -(cp &a,cp &b){return cp(a.x-b.x,a.y-b.y);}
cp operator *(cp &a,cp &b){return cp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
cp operator /(cp &a,ld b){return cp(a.x/b,a.y/b);}
cp a1[500010];
cp a2[500010];
cp a3[500010];
cp w1[500010];
cp w2[500010];
int rev[500010];
int N;
namespace fft
{
void get(int n)
{
N=1;
while(N<n)
N<<=1;
int i;
for(i=2;i<=N;i<<=1)
{
w1[i]=cp(cos(ld(2*pi/i)),sin(ld(2*pi/i)));
w2[i]=conj(w1[i]);
}
for(i=0;i<N;i++)
rev[i]=(rev[i>>1]>>1)|(i&1?(N>>1):0);
}
void fft(cp *a,int t)
{
int i,j,k;
cp w,wn,u,v;
for(i=0;i<N;i++)
if(rev[i]<i)
swap(a[i],a[rev[i]]);
for(i=2;i<=N;i<<=1)
{
wn=t?w1[i]:w2[i];
for(j=0;j<N;j+=i)
{
w=cp(1);
for(k=j;k<j+i/2;k++)
{
u=a[k];
v=a[k+i/2]*w;
a[k]=u+v;
a[k+i/2]=u-v;
w=w*wn;
}
}
}
if(!t)
for(i=0;i<N;i++)
a[i]=a[i]/N;
}
}
ll a[500010];
ll b[500010];
ll c[500010];
ll d[500010];//答案
ll e[500010];
ll f[500010];
const ll A=1000;
const ll B=1000000;
void cheng(ll *a1,int n1,ll *a2,int n2,ll *a3,int n3)
{
int i,j;
for(i=0;i<n3;i++)
a3[i]=0;
for(i=0;i<n1;i++)
for(j=0;j<n2;j++)
a3[i+j]+=a1[i]*a2[j];
}
void clear(ll *a,int n)
{
int i;
for(i=0;i<n;i++)
a[i]=0;
}
void cheng(ll *a1,int n1,ll a2)
{
int i;
for(i=0;i<n1;i++)
a1[i]*=a2;
}
void jia(ll *a1,int n1,ll *a2,int n2,ll *a3,int n3)
{
int i;
for(i=0;i<n3;i++)
a3[i]=0;
for(i=0;i<n1||i<n2;i++)
{
ll s1=(i<n1?a1[i]:0);
ll s2=(i<n2?a2[i]:0);
a3[i]+=s1+s2;
}
}
void jia(ll *a1,ll *a2,int n2)
{
int i;
for(i=0;i<n2;i++)
a1[i]+=a2[i];
}
void solve(int l,int r)
{
if(l==r)
{
// d[l]=b[l];
// c[l]=a[l];
d[l*2]=b[l]%A;
d[l*2+1]=b[l]/A;
c[l*2]=a[l]%A;
c[l*2+1]=a[l]/A;
return;
}
if(r-l+1<=20)
{
int i,j;
int len=(r-l+1);
clear(c+l*2,len*2);
clear(d+l*2,len*2);
c[l*2]=1;
for(i=0;i<len;i++)
{
memcpy(e+l*2,c+l*2,len*sizeof(ll)*2);
cheng(e+l*2,len*2,b[l+i]);
for(j=0;j<len*2-1;j++)
{
e[l*2+j+1]+=e[l*2+j]/A;
e[l*2+j]%=A;
}
jia(d+l*2,e+l*2,len*2);
for(j=0;j<len*2-1;j++)
{
d[l*2+j+1]+=d[l*2+j]/A;
d[l*2+j]%=A;
}
cheng(c+l*2,len*2,a[l+i]);
for(j=0;j<len*2-1;j++)
{
c[l*2+j+1]+=c[l*2+j]/A;
c[l*2+j]%=A;
}
}
return;
}
int mid=(l+r)>>1;
solve(l,mid);
solve(mid+1,r);
int llen=mid-l+1;
int rlen=r-mid;
int len=r-l+1;
llen*=2;
rlen*=2;
len*=2;
// if(len>50000&&r==69999)
// int xfz=1;
// if(l==0)
// int xfz=1;
int i;
fft::get(len);
for(i=0;i<llen;i++)
a1[i]=cp(c[l*2+i]);
for(i=llen;i<N;i++)
a1[i]=cp();
for(i=0;i<rlen;i++)
{
a2[i]=cp(c[mid*2+2+i]);
a3[i]=cp(d[mid*2+2+i]);
}
for(i=rlen;i<N;i++)
a2[i]=a3[i]=cp();
fft::fft(a1,1);
fft::fft(a2,1);
fft::fft(a3,1);
for(i=0;i<N;i++)
{
a2[i]=a2[i]*a1[i];
a3[i]=a3[i]*a1[i];
}
fft::fft(a2,0);
fft::fft(a3,0);
// if(len>50000&&r==69999)
// int xfz=1;
for(i=0;i<len;i++)
{
c[l*2+i]=ll(a2[i].x+0.4);
e[l*2+i]=ll(a3[i].x+0.4);
}
for(i=0;i<llen;i++)
e[l*2+i]+=d[l*2+i];
for(i=0;i<len;i++)
d[l*2+i]=e[l*2+i];
for(i=0;i<len-1;i++)
{
c[l*2+i+1]+=c[l*2+i]/A;
c[l*2+i]%=A;
d[l*2+i+1]+=d[l*2+i]/A;
d[l*2+i]%=A;
}
// cheng(c+l,llen,d+mid+1,rlen,e,len);
// jia(e,len,d+l,llen,f,len);
// int i;
// for(i=0;i<len;i++)
// d[l+i]=f[i];
// for(i=0;i<len-1;i++)
// {
// d[l+i+1]+=d[l+i]/A;
// d[l+i]%=A;
// }
// cheng(c+l,llen,c+mid+1,rlen,e,len);
// for(i=0;i<len;i++)
// c[l+i]=e[i];
// for(i=0;i<len-1;i++)
// {
// c[l+i+1]+=c[l+i]/A;
// c[l+i]%=A;
// }
}
int main()
{
// freopen("conv.in","r",stdin);
// freopen("conv-2.out","w",stdout);
int n;
scanf("%d",&n);
int i;
for(i=0;i<n;i++)
scanf("%d",&a[i]);
for(i=0;i<n;i++)
scanf("%d",&b[i]);
solve(0,n-1);
for(i=2*n-1;!d[i];i--);
printf("%d",d[i]);
for(i--;i>=0;i--)
// output(d[i]);
printf("%03d",d[i]);
putchar('\n');
// int n=4;
// fft::get(n);
// a1[0]=cp(1);
// a1[1]=cp(2);
// a2[0]=cp(1);
// a2[1]=cp(2);
// fft::fft(a1,1);
// fft::fft(a2,1);
// int i;
// for(i=0;i<N;i++)
// a1[i]=a1[i]*a2[i];
// fft::fft(a1,0);
return 0;
}

【XSY1529】小Q与进位制 分治 FFT的更多相关文章

  1. (2016北京集训十)【xsy1529】小Q与进位制 - 分治FFT

    题意很简单,就是求这个数... 其实场上我想出了分治fft的正解...然而不会打...然后打了个暴力fft挂了... 没啥好讲的,这题很恶心,卡常卡精度还爆int,要各种优化,有些dalao写的很复杂 ...

  2. 2016北京集训 小Q与进位制

    题目大意 一个数每一位进制不同,已知每一位的进制,求该数的十进制表达. 显然有 $$Ans=\sum\limits_{i=0}^{n-1}a_i \prod\limits_{j=0}^{i-1}bas ...

  3. BZOJ5125: [Lydsy1712月赛]小Q的书架【决策单调性优化DP】【BIT】【莫队】【分治】

    小Q有n本书,每本书有一个独一无二的编号,现在它们正零乱地在地上排成了一排. 小Q希望把这一排书分成恰好k段,使得每段至少有一本书,然后把每段按照现在的顺序依次放到k层书架的每一层上去.将所有书都放到 ...

  4. 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT)

    再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Blueste ...

  5. [Codeforces 553E]Kyoya and Train(期望DP+Floyd+分治FFT)

    [Codeforces 553E]Kyoya and Train(期望DP+Floyd+分治FFT) 题面 给出一个\(n\)个点\(m\)条边的有向图(可能有环),走每条边需要支付一个价格\(c_i ...

  6. bzoj 4815: [Cqoi2017]小Q的表格 [数论]

    4815: [Cqoi2017]小Q的表格 题意: 单点修改,查询前缀正方形和.修改后要求满足条件f(a,b)=f(b,a), b×f(a,a+b)=(a+b)*f(a,b) 一开始sb了认为一次只会 ...

  7. hdu 5730 Shell Necklace [分治fft | 多项式求逆]

    hdu 5730 Shell Necklace 题意:求递推式\(f_n = \sum_{i=1}^n a_i f_{n-i}\),模313 多么优秀的模板题 可以用分治fft,也可以多项式求逆 分治 ...

  8. 【XSY2666】排列问题 DP 容斥原理 分治FFT

    题目大意 有\(n\)种颜色的球,第\(i\)种有\(a_i\)个.设\(m=\sum a_i\).你要把这\(m\)个小球排成一排.有\(q\)个询问,每次给你一个\(x\),问你有多少种方案使得相 ...

  9. 【BZOJ5119】【CTT2017】生成树计数 DP 分治FFT 斯特林数

    CTT=清华集训 题目大意 有\(n\)个点,点权为\(a_i\),你要连接一条边,使该图变成一颗树. 对于一种连边方案\(T\),设第\(i\)个点的度数为\(d_i\),那么这棵树的价值为: \[ ...

随机推荐

  1. Python_每日习题_0006_斐波那契数列

    程序设计: 斐波那契数列(Fibonacci sequence),从1,1开始,后面的每一项等于前面两项之和. 图方便就递归实现,图性能就用循环. # for 循环 target = int(inpu ...

  2. c++入门之浅拷贝和深拷贝

    关于这方面的知识:见一篇精辟博文:https://blog.csdn.net/feitianxuxue/article/details/9275979

  3. c#中用sql存储过程

    string connstr = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionStri ...

  4. 砝码组合(dfs)

    砝码组合  题目内容:用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量.如果只有5个砝码,重量分别是1,3,9,27,81.则它们可以组合称出1到121之间任意整数重量(砝码允许放在左右两 ...

  5. DWZ富客户端框架(jQuery RIA framework)

    该OA项目前端采用的是DWZ框架来进行实现的. 本来想写点总结的,但发现真没啥好写的.中文的文档,到时候用到直接看文档就好.

  6. ascii、unicode、utf-8、gbk 区别

    原文:https://blog.csdn.net/u010262331/article/details/46013905 ASCII:遇上0×10, 终端就换行: 遇上0×07, 终端就向人们嘟嘟叫: ...

  7. js 正则进阶regexp

    一.匹配中文,英文字母和数字及_: const reg = /^[\u4e00-\u9fa5\w]+$/; const str1 = 'shangyy'; const str2 = '尚悦悦ww123 ...

  8. tomcat启动的时候报错Failed to start component

    在idea中运行tomcat时,遇到异常,异常信息如下: 16-Jan-2018 16:33:37.325 信息 [localhost-startStop-1] org.apache.catalina ...

  9. 解决 linux 下面解压缩 中文文件名乱码问题的方法 unzip -O CP936

    Linux 解压缩 zip包中文目录出现乱码的问题. 出现问题如图示: unzip -O CP936 xxx.zip 用这种方式处理一下就好了.

  10. 《Effective C++》资源管理:条款13-条款17

    条款13:以对象管理资源 为了防止资源泄漏,请使用RAII(Resource Acquisition Is Initialization)对象,在构造函数里面获得资源,在析构函数里面释放资源 auto ...