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,看如何的去处理每一轮
显然,每一轮有的做法,就是遍历所有的a。在整个过程中会发现,的值其实是在循环的,而每一个完整循环中的数量是固定的,不需要逐个去计算完整循环中的。只需要将一个完整循环中的算出来,然后乘上循环数就行。接下来只剩下不完整的一个循环,其的数量也是可以直接算出来的。如此便能的去处理每一轮(注意需要特判一下S = 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. 数学尖子生
思路:定义是包含了因子的数的集合,为的大小。对于每一个询问,答案为。
根据定义,有,因此答案式可以化简为
接下来考虑如何求,中有多少个数包含了因子 。可以想到:这些数是的倍数。也就是说
最终注意一下爆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;
}