蓝桥杯第二场小白入门赛(1~5)(对不起,我线段树太菜了)

1.模拟

2.贪心

3.二分

4.数论

5.数论

6.线段树(线段树还是练少了...)

1. 蓝桥小课堂-平方和

直接模拟,注意数据范围

#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second 
#define endl '\n'
#define int unsigned long long
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
LL gcd(LL a, LL b){
	return b > 0 ? gcd(b , a % b) : a;
}

LL lcm(LL a , LL b){
	return a / gcd(a , b) * b;
}
int n , m;
vector<int>a(N , 0);
void init(int n){
	for(int i = 0 ; i <= n ; i ++){
		a[i] = 0;
	}
}
void solve() 
{
	cin >> n;
	cout << (n * (n + 1) * (2 * n + 1) / 6);
}            
signed main() 
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout.precision(10);
    int t=1;
	///cin>>t;
    while(t--)
    {
    	solve();
    }
    return 0;
}

2. 房顶漏水啦

       

贪心,分别找到最边缘的四块木板,然后考虑需要多大的正方形才能完全覆盖。

#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second 
#define endl '\n'
#define int long long
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
LL gcd(LL a, LL b){
	return b > 0 ? gcd(b , a % b) : a;
}

LL lcm(LL a , LL b){
	return a / gcd(a , b) * b;
}
int n , m;
vector<int>a(N , 0);
void init(int n){
	for(int i = 0 ; i <= n ; i ++){
		a[i] = 0;
	}
}
void solve() 
{
	cin >> n >> m;
	pair<int,int>ans[m];
	for(int i = 0 ; i < m ; i ++){
		cin >> ans[i].x >> ans[i].y;
	}
	int l_min = ans[0].x , l_max = ans[0].x , r_min = ans[0].y , r_max = ans[0].y;
	for(int i = 1 ; i < m ; i ++){
		l_min = min(l_min , ans[i].x);
		l_max = max(l_max , ans[i].x);
		r_min = min(r_min , ans[i].y);
		r_max = max(r_max , ans[i].y);
	}
	cout << max(r_max - r_min , l_max - l_min) + 1;
}            
signed main() 
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout.precision(10);
    int t=1;
//	cin>>t;
    while(t--)
    {
    	solve();
    }
    return 0;
}

 3. 质数王国

 

先用素数筛找素数,然后二分找出最近的素数。

        

#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second 
#define endl '\n'
#define int long long
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
LL gcd(LL a, LL b){
	return b > 0 ? gcd(b , a % b) : a;
}

LL lcm(LL a , LL b){
	return a / gcd(a , b) * b;
}
int n , m;
vector<int>a(N , 0);
void init(int n){
	for(int i = 0 ; i <= n ; i ++){
		a[i] = 0;
	}
}
vector<LL>prime;//存储素数
bool vis[N+5];
void su() 
{
	for(int i=2;i<=N;i++)
	{
		if(!vis[i])
		prime.pb(i);
		for(int j=0;j < prime.size() && prime[j] * i <= N;j ++)
		{
			vis[prime[j]*i]=1;
			if(i % prime[j]==0)
			break;
		}
	}
} 
void solve() 
{
	set<int>prim;
	for(auto it : prime){
		prim.insert(it);
	}
	cin >> n;
	int ans = 0;
	for(int i = 0 ; i < n ; i ++){
		int x;
		cin >> x;
		auto it = prim.lower_bound(x);
		int res = *it - x;
		if(it != prim.begin()){
			it--;
			res = min(res , x - *it);
		}
		ans += res;
	}
	cout << ans;
}            
signed main() 
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout.precision(10);
    su();
    int t=1;
	//cin>>t;
    while(t--)
    {
    	solve();
    }
    return 0;
}

4. 取余

        

思路:考虑遍历所有的b,看如何O(1)的去处理每一轮

显然,每一轮有O(N)的做法,就是遍历所有的a。在整个过程中会发现,a\%b的值其实是在循环的,而每一个完整循环中f(a,b)的数量是固定的,不需要逐个去计算完整循环中的f(a,b)。只需要将一个完整循环中的f(a,b)算出来,然后乘上循环数就行。接下来只剩下不完整的一个循环,其f(a,b)的数量也是可以直接算出来的。如此便能O(1)的去处理每一轮(注意需要特判一下S = 0 的情况,因为一轮循环中的a\%b[1 , 2 , 3 .... b - 1 , 0])。

#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second 
#define endl '\n'
#define int long long
const LL maxn = 4e05+7;
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
LL gcd(LL a, LL b){
	return b > 0 ? gcd(b , a % b) : a;
}

LL lcm(LL a , LL b){
	return a / gcd(a , b) * b;
}
int n , m;
vector<int>a(N , 0);
void init(int n){
	for(int i = 0 ; i <= n ; i ++){
		a[i] = 0;
	}
}
void solve() 
{
	int a , b , s , t;
	cin >> a >>  b >> s >> t;
	int ans = 0;
	if(s != 0){	
		for(int i = 1 ; i <= b ; i ++){
			if(i <= s){
				continue;
			}
			else{
				int lun = a / i;
				int res = a - lun * i;
				ans += lun * min(t - s + 1, i - s);
				if(res >= s){
					ans += min(t - s + 1 , res - s + 1);
				}
			}
		}
	}
	else{
		s = 1;
		for(int i = 1 ; i <= b ; i ++){
			if(i == 1){
				ans += a / i;
			}
			else{
				int lun = a / i;
				int res = a - lun * i;
				ans += lun * min(t - s + 1, i - s);
				ans += lun;
				if(res >= s){
					ans += min(t - s + 1 , res - s + 1);
				}
			}
		}		
	}
	cout << ans << endl;
}            
signed main() 
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout.precision(10);
    int T=1;
	///cin>>t;
    while(T--)
    {
    	solve();
    }
    return 0;
}

5. 数学尖子生

       

 思路:定义S(i)[1,n]包含了因子1,2,3,4...i的数的集合,|S(i)|S(i)的大小。对于每一个询问,答案为|S(a - 1)| - |S(a-1)\wedge (S(a)\vee S(a+1)...\vee S(n) )|

        根据定义,有\forall i(S[i + 1]\subseteq S[i]),因此答案式可以化简为|S(i - 1)| - | S(i)|

        接下来考虑如何求|S(i)|[1,n]中有多少个数包含了因子 1,2,3,4...i。可以想到:这些数是lcm[1,2,3,4..i]的倍数。也就是说|S(i)| = n/lcm[1,2,3,4....i]

        最终注意一下爆longlong即可。

#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second 
#define endl '\n'
#define int long long
const LL maxn = 4e05+7;
const LL N = 1e06+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;//小根堆
priority_queue<LL> ma;//大根堆
LL gcd(LL a, LL b){
	return b > 0 ? gcd(b , a % b) : a;
}

LL lcm(LL a , LL b){
	return a / gcd(a , b) * b;
}
int n , m;
int inv[N];
void solve() 
{
	cin >> n >> m;
	if(n > 41){
		cout << 0 << endl;
	}
	else
		cout << (m / inv[n - 1] - m / inv[n])<< endl;
}            
signed main() 
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout.precision(10);
    int t=1;
    inv[1] = 1;
    inv[0] = 1;
    for(int i = 2 ; i <= 41 ; i ++){
    	int x = gcd(i , inv[i - 1]);
    	inv[i] = lcm(i , inv[i - 1]);
    }
	cin>>t;
    while(t--)
    {
    	solve();
    }
    return 0;
}

        

        

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值