[ BZOJ 2757 ]Blinker的仰慕者

Blinker的仰慕者[L,R] 之间满足各位数字乘积为\(k\) 的数字有多少个.\((L,R \leq 10^{18})\)

  • \(f[i][j][k]:\)\(i\)位数,\(j\)代表与上限的大小关系,\(k\)是积

    • \(k\) 太大:上限可达 \(9^{18}\)
  • 优化:因为每次都是乘\([0,9]\)之间的整数,因此可以将\(k\)拆成四维,则状态为:

    • \(f[i][j][a][b][c][d]\) 其中\(i,j\)的含义不变,\(a,b,c,d\)各代表\(2,3,5,7\)的指数.

但是还是太大!因为状态一共有 \(18\times 2\times log_210^{18}\times log_310^{18}\times log_510^{18}\times log_710^{18} = 44543912\)

此时将[\(1,10^{18}\)]范围内所有质因子只有\(2,3,5,7\)的数字统计一遍,发现只有 \(66061\) 个数
因此可以先打一个表,记录 \([1,10^{18}]\) 之间质因子只含有 \(2,3,5,7\) 的数字个数.
状态:\(f[i][j]\) 为前 \(i\) 个数,乘积为表中的第\(j\)项时的方案数.


枚举质因子只含有 \(2,3,5,7\) 的数

数表生成器:

typedef long long ll;
priority_queue<ll,vector<ll>,greater<ll> >q;
vector<ll>ans;
map<ll,bool>vis;
void gen(vector<ll>& ans,const ll& maxn) {//生成 [1,maxn] 中质因子只包含 2,3,5,7 的数字,保存在 ans 中。
	const ll b[4]= {2,3,5,7};
	q.push(1);
	vis[1]=1;
	while(!q.empty()) {
		ll u=q.top();
		q.pop();
		ans.push_back(u);
		for(int i=0; i<4; i++) {
			ll v=u*b[i];
			if(!vis.count(v) && v<=maxn) {
				q.push(v);
				vis[v]=1;
			}
		}
	}
	sort(ans.begin(),ans.end());
}
posted @ 2018-10-09 16:27  昤昽  阅读(200)  评论(0编辑  收藏  举报