牛客挑战赛44 题解

切T1+T2+T4。尤其T4我是唯一一个写正解切了,但一血被一个NTT卡常选手占了。

T1

发现答案只有\(3,5,7\)

具体证明考虑\(p,p+2,p+4\)\(3\)意义下互不相同,所以肯定存在一个为\(3\)的倍数。

T2

lj题目大意。

按照物理课上学的知识来分析一下。

跑个最短路求出每个点的电势,再判一下\(1\)\(n\)是否连通、\(1\)是否电势最高、\(n\)是否电势最低,每条边连接的两边的点电势差是否为这条边的电压。

T3

正解真就min_25筛呗。。。自认为比赛时写不出min_25而且看有很多人切于是死活不肯写min_25筛。

这里的min_25筛还是只用算\(g\)不用算\(S\)的阉割版本。

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define N 1000010
#define ll long long
ll n,sq;
int p[N],np;
bool inp[N];
ll w[N];
int m;
int id1[N],id2[N];
#define id(x) (x<=sq?id1[x]:id2[n/x])
ll g[N];
int main(){
	freopen("in.txt","r",stdin);
	scanf("%lld",&n),sq=sqrt(n);
	for (int i=2;i<=sq;++i){
		if (!inp[i])
			p[++np]=i;
		for (int j=1;j<=np && i*p[j]<=sq;++j){
			inp[i*p[j]]=1;
			if (i%p[j]==0)
				break;
		}
	}
	for (ll i=1;i<=n;){
		ll j=n/(n/i),d=n/j;
		w[++m]=d;
		id(d)=m;
		i=j+1;
	}
	for (int i=1;i<=m;++i)
		g[i]=w[i]-1;
	for (int i=1;i<=np;++i){
		for (int j=1;j<=m && w[j]>=(ll)p[i]*p[i];++j){
			ll d=w[j]/p[i],k=id(d);
			g[j]-=g[k]-(i-1);
		}
	}
	ll s=g[id(n)];
	for (int k=1;k<=np;++k){
		ll x=(ll)p[k]*p[k];
		for (;x<=n;x*=p[k])
			s++;
	}
	printf("%lld\n",s);
	return 0;
}

T4

在此

T5

由于题解没有放图出来,所以不知道怎么构造的。

T6

比赛之后才发现是一道水题??

考虑\(a_i^2=a_{i-1}^2+a_{i-2}^2+a_{i-3}^2+2(a_{i-1}a_{i-2}+a_{i-1}a_{i-3}+a_{i-2}a_{i-3})\),如果我们能维护连续的三个\(a_i^2\)\(a_ia_i-1\)\(a_i\),就可以写出个线性的递推式,然后就可以用矩阵乘法优化了。

后面的那个斐波拉契平方和,可以试着用矩阵乘法卡过去。题解做法是搬出通项然后一波乱推。最后\(\sqrt 5\)的问题用定义一个类似于复数的东西处理。

最后看到评论区有人说\(\sum_{i=1}^nF_i^2=F_nF_{n+1}\)???

posted @ 2020-10-17 14:41  jz_597  阅读(94)  评论(0编辑  收藏  举报