2023牛客算法基础训练营补题2
E
解析
根据题意可以知道在不向下取整时是高中经典的双勾函数,最小值在 \(\sqrt{n}\) 取得
由于原函数是在该函数的基础上向下取整,所以原函数的图像是在双勾函数下的阶梯型函数(可以画画图
所以该题答案一定是在之前的基础上向左偏移,所以对左边进行二分即可
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int INF = 0x3f3f3f3f;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
int n,l,r;
int f(int x){
return n/x + x - 1;
}
void solve(){
cin >> n >> l >> r;
int m = sqrt(n);
int l1 = m;
int res = f(m);
if(m >= l && m <= r){
while(l < l1){
int mid = l + l1 >> 1;
if(f(mid) == res){
l1 = mid;
}
else l = mid + 1;
}
int r1 = m + 1;
if(r1 >= l && r1 <= r){
if(res <= f(r1)) cout << l << endl;
else cout << r1 << endl;
}
else cout << l << endl;
}
else{
if(m < l) cout << l << endl;
else if(m > r){
res = f(r);
while(l < r){
int mid = l + r >> 1;
if(f(mid) == res){
r = mid;
}
else l = mid + 1;
}
cout << l << endl;
}
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--){
solve();
}
return 0;
}
I
解析
可以考虑每个音符触发到新的区间所需要的最小h,一个音符5个区间最多要考虑4个h
初始化h为-INF(即每个音符都处在最左区间
用map维护h和每次发生变化时改变的权值。
遍历map中的每个值,遇到新的h即res发生变化(即对应的音符发生区间改变
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
map<int,int> mapp;
const int N = 2e5 + 5;
int s[N];
int v[7];
int c[7];
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
void solve(){
int n;
cin >> n;
for(int i = 1; i <= n; i++) cin >> s[i];
for(int i = 1; i <= 4; i++) cin >> c[i];
for(int i = 1; i <= 5; i++) cin >> v[i];
mapp.clear();
int ini = n * v[1];
for(int i = 1; i <= n; i++){
for(int j = 1; j <= 3; j++){
mapp[c[j] - s[i]] += v[j+1] - v[j];
}
mapp[c[4] - s[i] + 1] += v[5] - v[4];
}
int res = ini;
for(auto x: mapp){
ini += x.second;
res = max(res,ini);
}
cout << res << endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--){
solve();
}
return 0;
}
A
暴力
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
void solve(){
int n;
int l1,r1;
int l2,r2;
cin >> n;
cin >> l1 >> r1;
cin >> l2 >> r2;
int cnt = 0;
for(int i = l1; i <= r1; i++){
if(n - i >= l2 && n - i <= r2) cnt++;
}
cout << cnt << endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--){
solve();
}
return 0;
}
B
区间交集
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
void solve(){
int n;
int l1,r1;
int l2,r2;
cin >> n;
cin >> l1 >> r1;
cin >> l2 >> r2;
int cnt = 0;
int minn = n - l1;
int maxx = n - r1;
swap(minn,maxx);
if(l2 > maxx) cnt = 0;
else if(l2 <= maxx && maxx <= r2 && minn <=l2) cnt = maxx - l2 + 1;
else if(maxx >= r2 && minn <= l2) cnt = r2 - l2 + 1;
else if(minn >= l2 && minn <= r2 && maxx >= l2 && maxx <= r2) cnt = maxx - minn + 1;
else if(minn >= l2 && minn <= r2 && maxx >= r2) cnt = r2 - minn + 1;
else if(minn > r2) cnt = 0;
cout << cnt << endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--){
solve();
}
return 0;
}
C
前缀和+差分
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int M = 998244353;
const int N = 4e5 + 5;
int cf[N];
int pre[N];
pair<int,int> pii[N];
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n,m;
cin >> n >> m;
for(int i = 1; i <= m; i++) {
int l,r;
cin >> l >> r;
pii[i].first = l;
pii[i].second = r;
cf[r+1] -= 1;
cf[l] += 1;
}
for(int i = 1; i <= n; i++) pre[i] = pre[i-1] + cf[i];
for(int i = 1; i <= n; i++) pre[i] = pre[i-1] + pre[i];
int res = 0;
for(int i = 1; i <= m; i++){
int minn = n - pii[i].second;
int maxx = n - pii[i].first;
if(pii[i].first > maxx) res = (res + (pre[maxx] - pre[minn-1])) % M;
else if(pii[i].first <= maxx && maxx <= pii[i].second && minn <= pii[i].first) {
int cnt = maxx - pii[i].first + 1;
res = (res + (pre[maxx] - pre[minn-1] - cnt)) % M;
}
else if(maxx >= pii[i].second && minn <= pii[i].first) {
int cnt = pii[i].second - pii[i].first + 1;
res = (res + (pre[maxx] - pre[minn-1] - cnt)) % M;
}
else if(minn >= pii[i].first && minn <= pii[i].second && maxx >= pii[i].first && maxx <= pii[i].second) {
int cnt = maxx - minn + 1;
res = (res + (pre[maxx] - pre[minn-1] - cnt)) % M;
}
else if(minn >= pii[i].first && minn <= pii[i].second && maxx >= pii[i].second) {
int cnt = pii[i].second - minn + 1;
res = (res + (pre[maxx] - pre[minn-1] - cnt)) % M;
}
else if(minn > pii[i].second) res = (res + (pre[maxx] - pre[minn-1])) % M;
}
cout << res << endl;
return 0;
}
D
贪心
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 2e5 + 5;
int cen[N];
int head[N];
int val[N];
int idx = 1;
struct edge{
int b,ne,w;
}edge[2*N];
void add(int a,int b,int c){
edge[idx].b = b;
edge[idx].w = c;
edge[idx].ne = head[a];
head[a] = idx++;
}
void dfs(int x,int fa){
cen[x] = cen[fa]+1;
for(int i = head[x]; i != 0; i = edge[i].ne){
if(edge[i].b != fa) dfs(edge[i].b,x);
}
}
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
for(int i = 2; i <= n; i++){
int p;
cin >> p;
add(i,p,0);
add(p,i,0);
}
for(int i = 1; i <= n; i++) cin >> val[i];
dfs(1,0);
sort(cen+1,cen+1+n);
sort(val+1,val+1+n);
int res = 0;
for(int i = 1; i <= n; i++) res += cen[i] * val[i];
cout << res << endl;
return 0;
}
F
简单DFS
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 5e5 + 5;
int mg[N][5];
int flag;
int n,k;
bool dfs(int x,int y){
if(x == n && y == 3) {
return true;
}
if(mg[x][y] == 2) {
return true;
}
if(mg[x][y] == 1) {
flag = 0;
return false;
}
mg[x][y] = 2;
bool p = false,q = false;
if(x+1 <= n) p = dfs(x+1,y);
if(y+1 <= 3) q = dfs(x,y+1);
if(!p && !q) {
mg[x][y] = 1;
return false;
}
return true;
}
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
void solve(){
cin >> n >> k;
flag = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= 3; j++)
mg[i][j] = 0;
}
for(int i = 1; i <= k; i++){
int x,y;
cin >> x >> y;
mg[x][y] = !mg[x][y];
}
dfs(1,1);
int res = 0;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= 3; j++){
if(mg[i][j] == 2) res++;
}
}
cout << res << endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--){
solve();
}
return 0;
}
H
二分
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 1e5 + 5;
int s[N];
vector<int> vec;
int pre[N];
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
void solve(){
vec.clear();
int n;
cin >> n;
for(int i = 1; i < N; i++){
s[i] = 0;
}
for(int i = 1; i <= n; i++){
int x;
cin >> x;
s[x]++;
}
int maxx = 0;
for(int i = 1; i < N; i++){
maxx = max(maxx,s[i]);
if(s[i]) vec.push_back(s[i]);
}
sort(vec.begin(),vec.end());
pre[0] = vec[0];
for(int i = 1; i < (int)vec.size(); i++)
pre[i] = pre[i-1] + vec[i];
for(int i = 1; i <= n; i++){
int l = 0,r = (int)vec.size()-1;
while(l < r){
int mid = l + r >> 1;
if(vec[mid] > i) r = mid;
else l = mid + 1;
}
int p = vec.size();
p -= 1;
int res = 0;
if(vec[l] <= i) {
res = pre[p];
cout << res << endl;
continue;
}
if(l != 0) {
res = pre[l-1];
}
res += (p - l + 1) * (i-1);
cout << res << endl;
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--){
solve();
}
return 0;
}
J
数学+找规律
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 1e5 + 5;
int matrix[N];
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
void solve(){
int n;
cin >> n;
int zc = 0,fc = 0;
int zs = 0,fs = 0;
for(int i = 1; i <= n; i++){
cin >> matrix[i];
if(matrix[i] >= 0) zc++,zs += matrix[i];
if(matrix[i] <= 0) fc++,fs += matrix[i];
}
int res = 0;
for(int i = 1; i <= n; i++){
if(matrix[i] >= 0)
res += n * matrix[i] + zs - fs;
else
res += zs - fs - n * matrix[i];
}
cout << res << endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while(t--){
solve();
}
return 0;
}
L
思维题
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N = 5005;
int s[N];
int vis[N][N];
int p1[N];
int res[N];
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
inline void print(int x){
if(x<0){
putchar('-');
x=-x;
}
if(x>9)
print(x/10);
putchar(x%10+'0');
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n,p;
cin >> n >> p;
for(int i = 1; i <= n; i++) cin >> s[i];
for(int i = 1; i <= n; i++) {
for(int j = i+1; j <= n; j++) {
int x = s[i] * s[j] % p;
p1[x]++;
vis[x][i]++;
vis[x][j]++;
}
}
for(int i = 1; i <= n; i++){
int q = s[i] % p;
for(int j = 0; j < p; j++){
int t = (j - q + p) % p;
int t1 = p1[t] - vis[t][i];
res[j] += t1*2;
}
}
for(int i = 0; i < p; i++){
cout << res[i] << " \n"[i == p-1];
}
return 0;
}