bzoj5019: [Snoi2017]遗失的答案

Description

小皮球在计算出答案之后,买了一堆皮肤,他心里很开心,但是一不小心,就忘记自己买了哪些皮肤了。==|||万

幸的是,他还记得他把所有皮肤按照1~N来编号,他买来的那些皮肤的编号(他至少买了一款皮肤),最大公约数

是G,最小公倍数是L。现在,有Q组询问,每组询问输入一个数字X,请你告诉小皮球,有多少种合法的购买方案中

,购买了皮肤X?因为答案太大了,所以你只需要输出答案mod1000000007即可。

Input

第一行,三个数字N,G,L,如题意所示。

第二行,一个数字Q,表示询问个数。

第三行,Q个数字,表示每个询问所问的X。

N,G,L≤10^8,Q≤10^5,1≤X≤10^8

Output

对于每一组询问,在一行中单独输出一个整数,表示这个询问的答案。

如果L%G非零则无解,将L的每个质因子看作一维,只有每维都取到最小(L中对应质数的次数)和最大幂次(G中对应质数的次数),才能得到对应的G和L,状压表示每一维的质因数次数是否取到最小/大值,可以选的数一定每维幂次在最小值和最大值之间,这样的数很少,在数据范围内不超过800个,分治dp得出某个数不选的方案数,用总方案数减去即得到某个数必选的方案数。时间复杂度为O((L的约数个数)*log(L的约数个数)*4^(L的不同质因子个数))

#include<bits/stdc++.h>
typedef int mat[259][259];
const int P=1e9+7;
int _(){
    int x=0,c=getchar();
    while(c<48)c=getchar();
    while(c>47)x=x*10+c-48,c=getchar();
    return x;
}
int n,g,l,qp,mx,fs[107],tg[107],tl[107],fp=0,ans[807];
inline void inc(int&a,int b){a+=b-P,a+=a>>31&P;}
struct dat{
    int v,s1,s2;
    bool operator<(const dat&w)const{return v<w.v;}
    void trans(mat a){
        for(int i=mx-1;i>=0;--i){
            int*m1=a[i],*m2=a[i|s1];
            for(int j=mx-1;j>=0;--j)inc(m2[j|s2],m1[j]);
        }
    }
}vs[807];
int vp=0;
void f1(int x){
    for(int i=2;i*i<=x;++i)if(x%i==0){
        do x/=i;while(x%i==0);
        fs[fp++]=i;
    }
    if(x>1)fs[fp++]=x;
}
void f2(int x,int*t){
    for(int i=0;i<fp;++i)for(;x%fs[i]==0;x/=fs[i],++t[i]);
}
void dfs(int w,int v,int s1,int s2){
    if(w==fp){
        if(v<=n)vs[++vp]=(dat){v,s1,s2};
        return;
    }
    for(int i=0;i<=tl[w];++i,v*=fs[w]){
        if(i>=tg[w])dfs(w+1,v,s1|(i==tg[w])<<w,s2|(i==tl[w])<<w);
    }
}
mat F[27];
int Fp=0,all;
void cpy(){
    for(int i=0;i<mx;++i)memcpy(F[Fp+1][i],F[Fp][i],sizeof(int)*mx);
    ++Fp;
}
void solve(int L,int R){
    if(L==R){
        if(R==1){
            cpy();
            vs[1].trans(F[Fp]);
            all=F[Fp][mx-1][mx-1];
            --Fp;
        }
        ans[L]=((all-F[Fp][mx-1][mx-1])%P+P)%P;
        return;
    }
    int M=L+R>>1;
    cpy();
    for(int i=M+1;i<=R;++i)vs[i].trans(F[Fp]);
    solve(L,M);
    --Fp;
    cpy();
    for(int i=L;i<=M;++i)vs[i].trans(F[Fp]);
    solve(M+1,R);
    --Fp;
}
void nos(){
    while(qp--)puts("0");
    exit(0);
}
int main(){
    n=_(),g=_(),l=_(),qp=_();
    f1(g),f1(l);
    std::sort(fs,fs+fp);
    fp=std::unique(fs,fs+fp)-fs;
    f2(g,tg),f2(l,tl);
    if(n<g)nos();
    for(int i=0;i<fp;++i)if(tg[i]>tl[i])nos();
    dfs(0,1,0,0);
    std::sort(vs+1,vs+vp+1);
    mx=1<<fp;
    F[0][0][0]=1;
    solve(1,vp);
    while(qp--){
        int x=_(),w=std::lower_bound(vs+1,vs+vp+1,(dat){x})-vs;
        if(w<=vp&&vs[w].v==x)printf("%d\n",ans[w]);
        else puts("0");
    }
    return 0;
}
时间: 2024-10-24 14:35:20

bzoj5019: [Snoi2017]遗失的答案的相关文章

「总结」多项式生成函数相关(1)

实在是太毒瘤了. 大纲. 多项式生成函数相关 默认前置:微积分,各种数和各种反演,FFT,NTT,各种卷积,基本和式变换. 主要内容: 泰勒展开,级数求和,牛顿迭代,主定理. //例题:在美妙的数学王国中畅游,礼物 多项式全家桶:乘法,求逆,求导,积分,分治,ln,exp,fwt,MTT. //城市规划,图的价值,染色,遗失的答案,按位或,随机游走. 生成函数:普通型生成函数,指数型生成函数计数原理. //猎人杀,遗忘的集合,生成树计数 例题. 一.泰勒展开和级数求和 1.泰勒展开 即对于任何函

「总结」多项式生成函数例题(2)

是\(FWT\)的例题了. 这里我做的题也不多,教练说尽可能多的讲. 只能给你们讲所有我做过的了. 1.按位或 http://hzoj.com/contest/126/problem/13 题解直接发链:https://www.cnblogs.com/Lrefrain/p/11655078.html 2.随机游走 http://hzoj.com/contest/220/problem/5 题解直接发链:https://www.cnblogs.com/Lrefrain/p/11655078.htm

【BZOJ5016】[Snoi2017]一个简单的询问 莫队

[BZOJ5016][Snoi2017]一个简单的询问 Description 给你一个长度为N的序列ai,1≤i≤N和q组询问,每组询问读入l1,r1,l2,r2,需输出 get(l,r,x)表示计算区间[l,r]中,数字x出现了多少次. Input 第一行,一个数字N,表示序列长度. 第二行,N个数字,表示a1-aN 第三行,一个数字Q,表示询问个数. 第4-Q+3行,每行四个数字l1,r1,l2,r2,表示询问. N,Q≤50000 N1≤ai≤N 1≤l1≤r1≤N 1≤l2≤r2≤N

[bzoj5017][Snoi2017]炸弹 tarjan缩点+线段树优化建图+拓扑

5017: [Snoi2017]炸弹 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 608  Solved: 190[Submit][Status][Discuss] Description 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足: Xi?Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆. 现在,请你帮忙计算一下,先把第 i 个炸弹引爆,将引爆多少个炸弹呢? Inp

2015年蓝桥杯省赛B组C/C++(试题+答案)

首先说,这次我是第二次参加蓝桥杯(大学里最后一次),可这次去连个三等都没拿到,有些心灰意冷,比上一次还差, 当时看到成绩出来的时候有些失落,但是跌倒了,再站起来继续跑就可以了.可能是状态不好吧,纯属自我安慰. 接下来我把今年的题目又重新做了一遍,写下了这篇博客,如果也有需要探讨答案的,希望可以有帮助. 第一题: 第1题:统计不含4的数字 题目大意 统计10000至99999中,不包含4的数值个数. 解题分析: 第一种解法: 数学方法,这种是在网上看到的一种解法: 最高位除了0.4不能使用,其余8

Codeforces 772A Voltage Keepsake - 二分答案

You have n devices that you want to use simultaneously. The i-th device uses ai units of power per second. This usage is continuous. That is, in λ seconds, the device will use λ·ai units of power. The i-th device currently has bi units of power store

Web前端面试题目及答案汇总

前端新人在面试前都比较焦虑,担心回答不上面试官的问题,也担心自己紧张,其实这都是心理没底的表现,今天和大家分享web前端开发常见面试题及答案,希望可以帮助即将面试的前端同学顺利通过面试. HTML/CSS部分 1.什么是盒子模型? 在网页中,一个元素占有空间的大小由几个部分构成,其中包括元素的内容(content),元素的内边距(padding),元素的边框(border),元素的外边距(margin)四个部分.这四个部分占有的空间中,有的部分可以显示相应的内容,而有的部分只用来分隔相邻的区域或

Java集合相关面试问题和答案

Java集合相关面试问题和答案 面试试题 1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector.Stack.HashTable和Array.随着集合的广泛使用,Java1.2提出了囊括所有集合接口.实现和算法的集合框架.在保证线程安全的情况下使用泛型和并发集合类,Java已经经历了很久.它还包括在Java并发包中,阻塞接口以及它们的实现.集合框架的部分优点如下: (1)使用核心集合类降低开发成本,而非实现我们自己的集合类.

HDU3081Marriage Match II(二分答案+并查集+最大流SAP)经典

Marriage Match II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2507    Accepted Submission(s): 856 Problem Description Presumably, you all have known the question of stable marriage match. A