题解 数

传送门

补题使我快乐

\(a, b, c\) 均用 \(b\) 表示
变形得 \(k=b(3b-4a)\)
感觉打表发现结论的概率比推出来大(雾
image
那么令
\(G_k(n)=\sum\limits_{i=2}^n[i\equiv 1\pmod 4\and(\operatorname{low}(i)>p_k\or \operatorname{ispri}(i))]\)
\(G'_k(n)=\sum\limits_{i=2}^n[i\equiv 3\pmod 4\and(\operatorname{low}(i)>p_k\or \operatorname{ispri}(i))]\)
Min_25 筛,两者互相转移即可

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 5000010
#define fir first
#define sec second
#define pb push_back
#define ll long long
// #define int long long

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline ll read() {
	ll ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

ll n;

namespace force{
	int ans;
	vector<pair<int, int>> buc[N];
	ll qval(int a, int d) {return 2*a*d+3*d*d-a*a;}
	void solve() {
		for (int d=1; d<=n; ++d)
			for (int a=1; a<=2*d||qval(a, d)>0; ++a)
				if (qval(a, d)<=n) {
					// assert(qval(a, d)>=max(a, d));
					buc[qval(a, d)].pb({a, d});
				}
		// for (int i=1; i<=1000; ++i) if (buc[i].size()) {
		// 	cout<<i<<": "; for (auto it:buc[i]) cout<<"("<<it.fir<<','<<it.sec<<") "; cout<<endl;
		// }
		for (int i=1; i<=n; ++i) if (buc[i].size()==1) ++ans;
		cout<<ans<<endl;
	}
}

namespace task1{
	bool npri[N];
	int pri[N], pcnt, ans;
	void solve() {
		for (int i=2; i<=n; ++i) {
			if (!npri[i]) pri[++pcnt]=i;
			for (int j=1; j<=pcnt&&i*pri[j]<=n; ++j) {
				npri[i*pri[j]]=1;
				if (!(i%pri[j])) break;
			}
		}
		if (n>=4) ++ans;
		if (n>=16) ++ans;
		for (int i=1; i<=pcnt; ++i) {
			if (pri[i]%4==3) ++ans;
			if (pri[i]!=2 && pri[i]*4<=n) ++ans;
			if (pri[i]!=2 && pri[i]*16<=n) ++ans;
		}
		cout<<ans<<endl;
	}
}

namespace liner_sieve{
	bool npri[N];
	int pri[N], pcnt;
	void solve() {
		ll ans=0;
		for (int i=2; i<=n; ++i) {
			if (!npri[i]) pri[++pcnt]=i, ans+=(i%4==3);
			for (int j=1; j<=pcnt&&i*pri[j]<=n; ++j) {
				npri[i*pri[j]]=1;
				if (!(i%pri[j])) break;
			}
		}
		cout<<ans<<endl;
	}
}

namespace task{
	bool npri[N];
	int pri[N], pcnt;
	ll id1[N], id2[N], g1[N], g2[N], sp1[N], sp2[N], uni[N], sqr, tot, ans;
	void solve(ll n) {
		sqr=sqrt(n); pcnt=tot=0;
		for (int i=2; i<=sqr; ++i) {
			if (!npri[i]) pri[++pcnt]=i, sp1[pcnt]=sp1[pcnt-1]+(i%4==1), sp2[pcnt]=sp2[pcnt-1]+(i%4==3);
			for (int j=1; j<=pcnt&&i*pri[j]<=sqr; ++j) {
				npri[i*pri[j]]=1;
				if (!(i%pri[j])) break;
			}
		}
		// memset(g1, 0, sizeof(g1));
		// memset(g2, 0, sizeof(g2));
		for (ll l=1,r; l<=n; l=r+1) {
			r=n/(n/l);
			ll t=n/l;
			uni[++tot]=t;
			if (t<=sqr) id1[t]=tot;
			else id2[n/t]=tot;
			g1[tot]=t/4+(t%4>=1)-1;
			g2[tot]=t/4+(t%4>=3);
			// for (int i=2; i<=t; ++i)
			// 	if (i%4==1) ++g1[tot];
			// 	else if (i%4==3) ++g2[tot];
			// cout<<"t: "<<t<<endl;
			// cout<<"g: "<<g1[tot]<<' '<<g2[tot]<<endl;
		}
		for (int i=1; i<=pcnt; ++i) {
			for (int j=1; j<=tot&&1ll*pri[i]*pri[i]<=uni[j]; ++j) {
				ll k=uni[j]/pri[i] <= sqr ? id1[uni[j]/pri[i]] : id2[n/(uni[j]/pri[i])];
				g1[j]=(g1[j]-(pri[i]%4==1)*(g1[k]-sp1[i-1])-(pri[i]%4==3)*(g2[k]-sp2[i-1]));
				g2[j]=(g2[j]-(pri[i]%4==1)*(g2[k]-sp2[i-1])-(pri[i]%4==3)*(g1[k]-sp1[i-1]));
			}
		}
		// cout<<"g1: "; for (int i=1; i<=tot; ++i) cout<<g1[i]<<' '; cout<<endl;
		// cout<<"g2: "; for (int i=1; i<=tot; ++i) cout<<g2[i]<<' '; cout<<endl;
	}
	void solve() {
		solve(n);
		ans+=g2[id2[1]];
		solve(n/4);
		ans+=g1[id2[1]]+g2[id2[1]];
		solve(n/16);
		ans+=g1[id2[1]]+g2[id2[1]];
		if (n>=4) ++ans;
		if (n>=16) ++ans;
		cout<<ans<<endl;
	}
}

signed main()
{
	freopen("number.in", "r", stdin);
	freopen("number.out", "w", stdout);

	n=read();
	// force::solve();
	// task1::solve();
	task::solve();

	return 0;
}
posted @ 2022-04-04 20:12  Administrator-09  阅读(3)  评论(0编辑  收藏  举报