牛客暑期多校训练营(第四场)解题报告

题目链接:https://ac.nowcoder.com/acm/contest/5669

 B-Basic Gcd Problem

题意:给你一个函数f_{c}(x)的定义,求解f_{c}(n)%10^9+7

牛客暑期多校训练营(第四场)解题报告_第1张图片

输入:

2
3 3
10 5

输出:

3
25

hint:规律

通过举例几个数就可以发现其实他就是在求 c^{cnt} ,其中cnt表示n的质因子幂次之和,比如 18=2^1*3^2 ,那么cnt=1+2=3,那么f_{c}(18)=c^3。由于输入量有点大,需要提前预处理一下这个cnt,这边采用的是dp处理。还有一点就是需要特判一下n=1的情况cnt=0,所以输出1。

#include
#define PB push_back
#define PII pair
#define PLL pair
#define FI first
#define SE second
#define mem(a) memset(a,0,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 0x3f3f3f3f;
const double pi=acos(-1),eps=1e-8;
const int maxn = 1e6+5;
const int mod = 1e9+7;
LL POW(LL a,LL b,LL p){
	LL ans=1;
	while(b){
		if(b&1)ans=ans*a%p;
		a=a*a%p;
		b>>=1; 
	}
	return ans;
}
int main(){
	vectordp(maxn+1,1);
	for(int i=2;i

 F-Finding the Order

题意:给你两条线和线上的四个点ABCD,其中AB在上面一条线 ,CD在下面一条线,给定AC,AD,BC,BD大小,A在B左边,问你四个点的先后顺序。

牛客暑期多校训练营(第四场)解题报告_第2张图片

 输入:

2
3 5 5 3
5 3 3 5

输出:

AB//CD
AB//DC

hint:

  • 在CD这条线上找一点设为E,f=AE+BE,过AB做中垂线交CD于F,此时f最小,然后离F点越远,f值越大。

牛客暑期多校训练营(第四场)解题报告_第3张图片

  • 当CD位于F点左侧时,只需要判断f_cf_d大小即可,前者大的话说明顺序是CD,否则是DC

  • 当CD位于F点右侧时,同理,前者大说明顺序是DC,否则是CD

  • 当CD位于F点两侧时,只需判断AC和BC大小以及AD和BD大小,那D举例子,如果说AD小于BD,那么就说明D在F左边,否则在右边,这就间接得出了CD的左右关系

牛客暑期多校训练营(第四场)解题报告_第4张图片

 

#include
#define PB push_back
#define PII pair
#define PLL pair
#define FI first
#define SE second
#define mem(a) memset(a,0,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 0x3f3f3f3f;
const double pi=acos(-1),eps=1e-8;
const int maxn = 1e6+5;
const int mod = 1e9+7;
int main(){
	int t;scanf("%d",&t);
	while(t--){
		int a,b,c,d;
		scanf("%d%d%d%d",&a,&b,&c,&d);
		int lc,rc,ld,rd;//cd相对f方向
		if(a

 H-Harder Gcd Problem

题意:给你1-n个数,让你取m对互不相同的数,且不放回,使得每对的两个数不互质,求m的最大值,并输出m对。

输入:

2
4
10

 输出:

1
2 4
4
3 9
5 10
8 2
4 6

hint:筛法+贪心

贪心策略:倒序查找质数,再以它为基准往上筛,因为大质数能配对的数相对小质数较少,要优先配对大的质数。当筛完的个数是奇数时,可以考虑把其中的一个偶数挑出来,存放在even数组里,最后在even数组中随机配对。

#include
#define PB push_back
#define PII pair
#define PLL pair
#define FI first
#define SE second
#define mem(a) memset(a,0,sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 0x3f3f3f3f;
const double pi=acos(-1),eps=1e-8;
const int maxn = 2e5+5;
const int mod = 1e9+7;
bool isprime[maxn],vis[maxn];
int prime[maxn],primesize;
void get_prime(int size){//欧拉筛素数 
	memset(isprime,true,sizeof(isprime));
	isprime[1]=false;
	for(int i=2;i<=size;i++){
		if(isprime[i])prime[primesize++]=i;
		for(int j=0;jp[maxn];
vectoreven;
void make(int l,int r){//配对 
	p[cnt].first=l;
	p[cnt++].second=r;
}
void create(vector&v){//数组随机配对 
	int len=v.size();
	for(int i=0;iv;
	for(int i=x;i<=n;i+=x){
		if(!vis[i]){
			v.push_back(i);
			vis[i]=true;
		}
	}
	int len=v.size();
	if(len==1)return;
	if(len&1){
		for(auto it=v.begin();it!=v.end();it++){
			if(*it%2==0){//挑出一个偶数
				even.push_back(*it);
				v.erase(it);
				break;
			}
		}
	}
	create(v);
}
void print(){//输出结果 
	printf("%d\n",cnt);
	for(int i=0;i1;i--){
			if(isprime[i]){
				f(i);
			}
		}
		create(even);
		print();
	}
	return 0;
}

 

你可能感兴趣的:(dp,素数筛,贪心)