csps analog Yan Emperor God 67, drop Lei Huang, Huang Genma problem solution

Questions surface: https://www.cnblogs.com/Juve/articles/11648975.html

Yan Emperor God:

Hit the table to find the law? And $ \ phi $ about?

The answer is $ \ sum \ limits_ {i = 2} ^ {n} \ phi (i) * \ frac {n} {i * i} $

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define int long long
 7 using namespace std;
 8 int n,ans=0;
 9 int prime[2000006],tot=0,phi[10000006];
10 bool vis[10000007];
11 void get_phi(int N){
12     vis[1]=phi[1]=1;
13     for(int i=2;i<=N;i++){
14         if(!vis[i]) prime[++tot]=i,phi[i]=i-1;
15         for(int j=1;j<=tot&&i*prime[j]<=N;j++){
16             vis[i*prime[j]]=1;
17             if(!(i%prime[j])){
18                 phi[i*prime[j]]=phi[i]*prime[j];
19                 break;
20             }
21             phi[i*prime[j]]=phi[i]*phi[prime[j]];
22         }
23     }
24 }
25 signed main(){
26     scanf("%lld",&n);
27     get_phi(sqrt(n)+1);
28     for(int i=2;i<=sqrt(n);++i)
29         ans+=phi[i]*(n/(i*i));
30     printf("%lld\n",ans);
31     return 0;
32 }
View Code

Huang Lei drop

Without a solid foundation, the earth was shaking. . . Hurry up out of LIS

Given sequence $ a_i $, provided f [i] expressed in a [i] at the end of the longest sequence length increase

则$f[i]=max{f[j]}+1(j<i&&a[j]<a[i])$

Set G [i] expressed in the number i is the longest rise ending sequence

则有$g[i]=\sum\limits_{j=1}^{i-1}[a[j]<a[i]&&f[j]=f[i]-1]*g[j]$

Thus there is a $ O (n ^ 2) $ Transfer

Then accelerate the transfer of Fenwick tree

Fenwick tree index is the weight, to ensure the sweep sequence j <i, query tree array a [i] -1 ensures a [j] <a [i], then the array can tree

Of course, it can segment tree, the principle is the same

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=1e5+5;
const int mod=123456789;
int n,typ,a[MAXN],mx=0;
pair<int,int>c[MAXN*10],f[MAXN],ans;//changdu,geshu
int lowbit(int x){
	return x&(-x);
}
int update(int pos,pair<int,int> val){
	for(int i=pos;i<=mx;i+=lowbit(i)){
		if(c[i].first<val.first) c[i]=val;
		else if(c[i].first==val.first) (c[i].second+=val.second)%=mod;
	}
}
pair<int,int> query(int pos){
	pair<int,int>res;
	res.first=0,res.second=1;
	for(int i=pos;i>0;i-=lowbit(i)){
		if(res.first<c[i].first) res=c[i];
		else if(res.first==c[i].first) (res.second+=c[i].second)%=mod;
	}
	return res;
}
int main(){
	scanf("%d%d",&n,&typ);
	for(int i=1;i<=n;++i) scanf("%d",&a[i]),mx=max(mx,a[i]);
	for(int i=1;i<=n;++i){
		f[i]=query(a[i]-1);
		++f[i].first;
		update(a[i],f[i]);
		if(ans.first<f[i].first) ans=f[i];
		else if(ans.first==f[i].first) (ans.second+=f[i].second)%=mod;
	}
	if(typ==0) printf("%d\n",ans.first);
	else printf("%d\n%d\n",ans.first,ans.second);
	return 0;
}

Genma Wong:

The contribution generated only white point, we classified according to the color of two white spots lca

If the two white dots lca white point, then this must be the white point two white dots in a

Enumeration from two white dots, white spots difficult to find only the depth of the [1, ni] There is a distance in its subtree white point i

Provided SUM [i] represents the number of i-layer before the white point W [i] represents the number of i-th layer of white spots, because the structure of each sub-tree have the same white point, the white point is located so that each subtree of the i the number of the white dot layer are equal

So the contribution is [ni] * w [i] sum,

If lca two white dots are black dots, white spots to enumerate two black dots distance i, j, only the depth of [1, n-max (i, j)] contributes to black spots

Set f [i] represents the number of black dots before the i-layer, then the answer is f [n-max (i, j)] * w [i] * w [j + 1], where i, j is the sequential , i denotes the point subtree son white dot in a black, j represents the point in the subtree son black black spots in

sum [], w [], f [] with recursive fib

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define int long long
 6 using namespace std;
 7 const int MAXN=5005;
 8 const int mod=123456789;
 9 int n,w[MAXN],sum[MAXN],f[MAXN],ans[MAXN<<1];
10 signed main(){
11     scanf("%lld",&n);
12     w[1]=w[3]=w[4]=1;w[2]=0;
13     for(int i=5;i<=n;++i) w[i]=(w[i-1]+w[i-2])%mod;
14     for(int i=1;i<=n;++i) sum[i]=(sum[i-1]+w[i])%mod;
15     f[1]=0,f[2]=f[3]=1;
16     for(int i=4;i<=n;++i) f[i]=(f[i-1]+f[i-2])%mod;
17     for(int i=1;i<=n;++i) f[i]=(f[i-1]+f[i])%mod;
18     for(int i=1;i<n;++i){
19         (ans[i]+=(sum[n-i]*w[i+1])%mod)%=mod;
20         for(int j=1;j<n;++j)
21             (ans[i+j]+=f[n-max(i,j)]*w[i]%mod*w[j+1]%mod)%=mod;
22     }
23     for(int i=1;i<=2*n;++i) printf("%lld ",ans[i]);
24     puts("");
25     return 0;
26 }
View Code

 

Guess you like

Origin www.cnblogs.com/Juve/p/11648967.html