【XSY1529】小Q与进位制 分治 FFT
题目大意
 小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的更多相关文章
- (2016北京集训十)【xsy1529】小Q与进位制 - 分治FFT
		题意很简单,就是求这个数... 其实场上我想出了分治fft的正解...然而不会打...然后打了个暴力fft挂了... 没啥好讲的,这题很恶心,卡常卡精度还爆int,要各种优化,有些dalao写的很复杂 ... 
- 2016北京集训 小Q与进位制
		题目大意 一个数每一位进制不同,已知每一位的进制,求该数的十进制表达. 显然有 $$Ans=\sum\limits_{i=0}^{n-1}a_i \prod\limits_{j=0}^{i-1}bas ... 
- BZOJ5125: [Lydsy1712月赛]小Q的书架【决策单调性优化DP】【BIT】【莫队】【分治】
		小Q有n本书,每本书有一个独一无二的编号,现在它们正零乱地在地上排成了一排. 小Q希望把这一排书分成恰好k段,使得每段至少有一本书,然后把每段按照现在的顺序依次放到k层书架的每一层上去.将所有书都放到 ... 
- 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT)
		再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Blueste ... 
- [Codeforces 553E]Kyoya and Train(期望DP+Floyd+分治FFT)
		[Codeforces 553E]Kyoya and Train(期望DP+Floyd+分治FFT) 题面 给出一个\(n\)个点\(m\)条边的有向图(可能有环),走每条边需要支付一个价格\(c_i ... 
- bzoj 4815: [Cqoi2017]小Q的表格 [数论]
		4815: [Cqoi2017]小Q的表格 题意: 单点修改,查询前缀正方形和.修改后要求满足条件f(a,b)=f(b,a), b×f(a,a+b)=(a+b)*f(a,b) 一开始sb了认为一次只会 ... 
- hdu 5730 Shell Necklace [分治fft | 多项式求逆]
		hdu 5730 Shell Necklace 题意:求递推式\(f_n = \sum_{i=1}^n a_i f_{n-i}\),模313 多么优秀的模板题 可以用分治fft,也可以多项式求逆 分治 ... 
- 【XSY2666】排列问题 DP 容斥原理 分治FFT
		题目大意 有\(n\)种颜色的球,第\(i\)种有\(a_i\)个.设\(m=\sum a_i\).你要把这\(m\)个小球排成一排.有\(q\)个询问,每次给你一个\(x\),问你有多少种方案使得相 ... 
- 【BZOJ5119】【CTT2017】生成树计数 DP 分治FFT 斯特林数
		CTT=清华集训 题目大意 有\(n\)个点,点权为\(a_i\),你要连接一条边,使该图变成一颗树. 对于一种连边方案\(T\),设第\(i\)个点的度数为\(d_i\),那么这棵树的价值为: \[ ... 
随机推荐
- POJ - 1177 线段树
			POJ - 1177 扫描线 这道题也算是一道扫描线的经典题目了. 只不过这道题是算周长,非常有意思的一道题.我们已经知道了,一般求面积并,是如何求的,现在我们要把扫描线进行改造一下,使得能算周长. ... 
- Python 内置库 sys用法
			sys模块功能众多,这边先学习几个常用的方法sys常见函数列表① sys.argv: 实现从程序外部向程序传递参数.其实sys.argv[]就是一个列表,里面的项为用户输入的参数,但是sys.argv ... 
- 结对项目——图形界面实现与dll动态链接
			先来一发软件截图~~~ 生成题目的界面 测评界面 第三块本来准备做一个文件历史记录的界面,但是由于时间不够,暂时还没做完. 图形界面的设计与实现 由于对传统的对话框风格不太满意,所以这次作业的图形界面 ... 
- vue入门(一)
			通过JS引用vue就不说了,重点说一下使用npm搭建vue脚手架. (以下是windows系统下的操作,win7+) npm是个命令行工具,在搭建vue脚手架之前首先要安装nodeJS,下面是node ... 
- jmeter压测
			一般压测时间:10-15分钟 这些并发用户一直在请求. 稳定性测试:一周 2天 衡量性能好坏的指标: tps 服务端每秒钟能处理的请求数 rt响应时间 就是你从发出请求到服务器端返回所需的时间. ... 
- 在Linux添加PYTHONPATH方法以及修改环境变量方法
			Linux下设置环境变量有三种方法,一种用于当前终端,一种用于当前用户,一种用于所有用户: 一:用于当前终端: 在当前终端中输入: export PATH=$PATH:<你的要加入的路径> ... 
- http1.0 1.1 与2.0
			长连接 HTTP 1.0需要使用keep-alive参数来告知服务器端要建立一个长连接,而HTTP1.1默认支持长连接. HTTP是基于TCP/IP协议的,创建一个TCP连接是需要经过三次握手的,有一 ... 
- 组建自己的局域网(可以将PC机实现为服务器)
			最近想要自己组建一个集群,并且可以通过外网访问,查了好些资料,终于成功了! 设备清单:笔记本1:(4g内存,500g硬盘),笔记本2:(12g内存,120g固态硬盘) (笔记本2上装有5台虚拟机,操作 ... 
- CentOs7安装docker(第二篇)
			一.Docker的概念: Docker: 镜像:Images 类似于面向对象中的类 容器:Container 类似于面向对象中的对象 它们之间的关系:容器Container通过镜像Images来创建 ... 
- mysql数据库在linux上的不同登录方式和权限
			在我的上两篇博文里,一篇是安装,一篇是配置远程登录, 提君博客原创 >>提君博客原创 http://www.cnblogs.com/tijun/ << 所以我的mysql的 ... 
