赛时过了4道,D、H签到,F题贪心莫名卡了很久,M题用了线段树莫名过了,正解应该是用贡献度(But想不出来),赛后发现B题思路完全正确,就是没有时间写了:(,I题字符串也是一道简单dp(可惜看不出来
B_生日蛋糕
题意
对于给定的n,f[n]表示n被1到n-1整除后出现的整数种数,最后对T次询问,输出1-n的f[n]之和、
注意n可以取到1e9,结果对1e9+7取模。
思路
打表找规律,f[n] = 1,2,2,3,3,4,4,4,5,5,5,6,6,6,6……非常的明显,对于f[n],其所出现的次数就是f[n]/2+1,因为这里n非常大,没有办法直接初始化,所以可以用结构体初始化,然后再二分查找n所对应的结构体。
代码
#include <bits/stdc++.h>
using namespace std;
#define maxn 1000001
const long long mod = 1e9 + 7;
struct node {
long long l, r;
long long num;
} s[100001];
long long sum[100001];
void qaq() {
for (int i = 1; i <= 100001; i++) {
if (i == 1) {
s[i].l = 1;
s[i].r = 1;
s[i].num = 1;
sum[i] = s[i].num;
} else {
s[i].l = s[i - 1].r + 1;
s[i].r = s[i].l + i / 2;
s[i].num = i / 2 + 1;
sum[i] = (s[i].num * i % mod + sum[i - 1] % mod) % mod;
}
};
}
int check(int x, long long n) {
if (s[x].l <= n && s[x].r >= n) {
return x;
} else if (s[x].l > n) {
return -1;
} else {
return -2;
}
}
int find(long long n) {
int l = 1, r = 100001, mid = (l + r) / 2;
int t = -3;
while (t < 0) {
t = check(mid, n);
if (t == -1) { //fn在l的左边
r = mid - 1;
} else { //fn在r的右边
l = mid + 1;
}
mid = (l + r) / 2;
}
return t;
}
int main() {
int t;
cin >> t;
qaq();
while (t--) {
long long n;
scanf("%lld", &n);
long long ans = 0;
int temp = find(n);
ans = (ans % mod + sum[temp - 1] % mod) % mod;
ans = (ans + (temp * (n - s[temp].l + 1) ) % mod) % mod;
printf("%lld\n", ans % mod);
}
}
F_筷子
题意
类似于牛客多校写的那道手套题,贪心找出最亏的情况,注意结果只跟种类数与奇偶性相关。
思路
先考虑摸一双筷子的情况,答案必然为(种类数+1)。剩下的直接看代码注释。
代码
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define int long long
const int N = 1e6 + 5;
int a[N];
signed main() {
int T;
scanf("%lld", &T);
while (T--) {
LL n, m;
scanf("%lld%lld", &n, &m);
LL sum1 = 0, num = 0;
for (int i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
sum1 += a[i] / 2ll;
if (a[i] % 2 == 1) {
num += a[i] / 2;
} else {
num += a[i] / 2 - 1;
}
}
if (sum1 < m) {
printf("-1\n");
continue;
}
LL ans = n + 1;
m--;//组成一双筷子的情况: 1 1 1 1 …… 1 2
//之后每加一双筷子就是能加2就加2,否则加1 (1 …… 1 2 3)(1 2 2)
//在已经组成一双筷子的情况下,如果a[i]是偶数,则它可以提供的加2次数是a[i]/2-1 ,奇数则是a[i]/2
if (num >= m) {
ans += 2 * m;
} else {
ans += 2 * num + (m - num);
}
printf("%lld\n", ans);
}
return 0;
}
K_某时某地
题意
给定一个正整数 n,请分别求出对于 k=0,1,⋯,9,有多少个三元组 (x,y,z) 满足 1≤x,y,z≤n 且x{YZ}≡k(mod10)。
思路
x^5与x 的个位数相同。
代码
待补
标签:return,河北省,long,int,补题,ans,lld,HBCPC2022,mod From: https://www.cnblogs.com/oddpointa/p/16840640.html