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;
}
posted @ 2023-01-19 16:39  Sun-Wind  阅读(64)  评论(0编辑  收藏  举报