C++小白训练第二天

C++小白训练第二天

以下为牛客挑战

今日收获

s[i]如果为前缀和,那么一段区间的和为,s[r-1]-s[l];
后缀的时候我们一定要(n+2)

知道了怎么求数的叶子节点个数的多少
cin>>u>>v;
dg[u]++,dg[v]++;

牛客挑战125

小苯的数组操作

E-小苯的数组操作_牛客周赛 Round 125

image-20260111120800410

1
8 4
6 2 4 1 5 3 4 6
1 2
3
2 6
3
27
23

这个题的思路就是

我们可以分两种情况去讨论

  • 当l和r没有交在一起时候,我们可以明显得到s1L+s2(n-R+1)+s[R-1]-s[L]**这个公式
s1原本的表示是前面的最小值,s2后面的最小值,s[R-1]-s[L]然后后面的就是区间和,s是前缀和

image-20260111120853418

  • 当这个存在交集时候我们可以直接分两种情况去判断,一个是L覆盖R那么L这一边全部变成数列中的最小值。
  • 当这个存在交集时候我们可以直接分两种情况去判断,一个是R覆盖L那么R这一边全部变成数列中的最小值。

但是我们可以讲起分成两段,被覆盖的一边退回原来的位置,就可以当成没有重合的两段做。

s1*L+s2*(n-R+1)+s[R-1]-s[L]

解题代码

#include<bits/stdc++.h>
#define int long long
#define lll __uint128_t
#define PII pair<int ,int>
#define endl '\n'
using namespace std;
#define yn(ans) printf("%s\n", (ans)?"Yes":"No");//快速打印
#define YN(ans) printf("%s\n", (ans)?"YES":"NO");
#define REP(i, e) for (int i = 0; i < (e); ++i)
#define REP1(i, s, e) for (int i = (s); i <=(e); ++i)
#define TESTS int t; cin >> t; while (t--)
#define TEST
const int N=3e5+10,M=1e3+10,mod=1e9+7;

void solve(){
    int n,q;
    cin>>n>>q;

    vector<int>a(n+1),s(n+1);//数组,和前缀和
    vector<int>pre(n+1,1e9);//前缀最小值
    vector<int>suf(n+2,1e9);//后缀最小值
    int L=0,R=n+1;
    int s1=pre[1],s2=pre[n];
    for(int i=1;i<=n;i++){
        cin>>a[i];
        s[i]=s[i-1]+a[i];
        pre[i]=min(pre[i-1],a[i]);
    }
    for(int i=n;i>0;i--){
        suf[i]=min(suf[i+1],a[i]);
    }
    while(q--){
        int op;
        cin>>op;
        if(op==1){
            int i;
            cin>>i;
            L=max(i,L);//就是选过的之前的区间,如果是子区间,直接用父区间来就行了
            if(L<R){
                s1=min(s1,pre[L]);
            }else{
               s1=pre[n];
               R=L+1;
            }
        }else if(op==2){
            int i;
            cin>>i;
            R=min(i,R);
            if(L<R){
                s2=min(s2,suf[R]);
            }else{
                s2=pre[n];
                L=R-1;
            }
        }else{
            cout<<s1*L+s2*(n-R+1)+s[R-1]-s[L]<<endl;
        }
    }

};
signed main(){

	std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    TESTS{
        solve();
    };

	return 0;
}

牛客周赛124

花绽晴窗含韵

A-花绽晴窗含韵_牛客周赛 Round 124

image-20260111133416854

签到题

解题代码

#include<bits/stdc++.h>
#define int long long
#define lll __uint128_t
#define PII pair<int ,int>
#define endl '\n'
using namespace std;
#define yn(ans) printf("%s\n", (ans)?"Yes":"No");//快速打印
#define YN(ans) printf("%s\n", (ans)?"YES":"NO");
#define REP(i, e) for (int i = 0; i < (e); ++i)
#define REP1(i, s, e) for (int i = (s); i <=(e); ++i)
#define TESTS int t; cin >> t; while (t--)
#define TEST
const int N=2e5+10,M=1e3+10,mod=1e9+7;
int a[N],b[N],c[N],pre[N];

signed main(){

	std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int A,B;
    cin>>A>>B;
    if(A>B){
       cout<<"Alice"<<endl;
    }else if(A==B){
        cout<<"Draw"<<endl;
    }else{
        cout<<"Bod"<<endl;
    }

	return 0;
}

寻梅踏雪问春

B-寻梅踏雪问春_牛客周赛 Round 124

image-20260111134224219

1 2 3 4 5 6

这个直接算点之间的距离就可以了

解题代码

#include<bits/stdc++.h>
#define int long long
#define lll __uint128_t
#define PII pair<int ,int>
#define endl '\n'
using namespace std;
#define yn(ans) printf("%s\n", (ans)?"Yes":"No");//快速打印
#define YN(ans) printf("%s\n", (ans)?"YES":"NO");
#define REP(i, e) for (int i = 0; i < (e); ++i)
#define REP1(i, s, e) for (int i = (s); i <=(e); ++i)
#define TESTS int t; cin >> t; while (t--)
#define TEST
const int N=2e5+10,M=1e3+10,mod=1e9+7;


signed main(){

	std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int a,b,c,d,e,f;
    cin>>a>>b>>c>>d>>e>>f;
    int x1=(d-b)*(d-b)+(c-a)*(c-a);
    int x2=(f-d)*(f-d)+(e-c)*(e-c);
    int x3=(f-b)*(f-b)+(e-a)*(e-a);
    if(x1==x2&&x2==x3){
        cout<<"YES"<<endl;
    }else{
        cout<<"NO"<<endl;
    }

	return 0;
}

夜揽星河入梦

C-夜揽星河入梦_牛客周赛 Round 124

image-20260111144158222

3
3 3
1 2 5
3 10
1 2 3
3 2
5 1 3

输出

YES
NO
YES

我的思路就是先进行排序,一开始我还是搞错,我之后才知道是平面,所以给顺序根本就是,我一开始忧虑太多,所以其实只要排一个序,然后每个的前缀连线,和后缀连线,当存在

a[i]+2==a[i+1]&&(f[i]+s[i+1]+1>=m

相当于 一个是前面的数的,因为连起来还要看整体的所以满足这个就行

解题代码

#include<bits/stdc++.h>
#define int long long
#define lll __uint128_t
#define PII pair<int ,int>
#define endl '\n'
using namespace std;
#define yn(ans) printf("%s\n", (ans)?"Yes":"No");//快速打印
#define YN(ans) printf("%s\n", (ans)?"YES":"NO");
#define REP(i, e) for (int i = 0; i < (e); ++i)
#define REP1(i, s, e) for (int i = (s); i <=(e); ++i)
#define TESTS int t; cin >> t; while (t--)
#define TEST
const int N=2e5+10,M=1e3+10,mod=1e9+7;
int a[N],b[N],c[N],pre[N];
void solve(){
    int n,m;
    cin>>n>>m;
    int now=0;
    bool ok= false;
    vector<int>f(n+1,1),s(n+1,1);

    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    sort(a,a+n);
    for(int i=1;i<=n-1;i++){
        if(a[i]==a[i-1]+1){
            f[i]=f[i-1]+1;
            now=max(now,f[i]);
        }
    }
    for(int i=n-2;i>=0;i--){
        if(a[i]==a[i+1]-1){
            s[i]=s[i+1]+1;
        }
    }
    if(now>=(m-1)){
        cout<<"YES"<<endl;
        return;
    }
    else{
        for(int i=0;i<n-1;i++){
            if(a[i]+2==a[i+1]&&(f[i]+s[i+1]+1>=m)){
                ok=true;
                break;
            }
        }
        if(ok==true){
            cout<<"YES"<<endl;
        }else{
            cout<<"NO"<<endl;

        }
    }

};
signed main(){

    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    TESTS{
        solve();
    };

    return 0;
}

云栖山涧听松

D-云栖山涧听松_牛客周赛 Round 124

image-20260111151333949

5
1 2
1 3
2 4
2 5
2

image-20260111151401176

​ 我们根据题目意思可以知道我们其实根本就要找叶子节点就可以,我们两两叶子节点相连接,或者叶子与不是叶子的连接,但是更优的还是叶子与叶子,除非多了就用别的连接

image-20260111151301853

解题代码

#include<bits/stdc++.h>
#define int long long
#define lll __uint128_t
#define PII pair<int ,int>
#define endl '\n'
using namespace std;
#define yn(ans) printf("%s\n", (ans)?"Yes":"No");//快速打印
#define YN(ans) printf("%s\n", (ans)?"YES":"NO");
#define REP(i, e) for (int i = 0; i < (e); ++i)
#define REP1(i, s, e) for (int i = (s); i <=(e); ++i)
#define TESTS int t; cin >> t; while (t--)
#define TEST
const int N=2e5+10,M=1e3+10,mod=1e9+7;
int a[N],b[N],c[N],pre[N];

signed main(){

	std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin>>n;
    vector<int>dg(n+1,0);
    for(int i=0;i<n-1;i++){
        int u,v;
        cin>>u>>v;
        dg[u]++,dg[v]++;
    }
    int ans=0;
    for(int i=0;i<=n;i++){
        if(dg[i]==1){
            ans++;
        }
    }

    int m=(ans+1)/2;//向上取整(n+b-1)/b
    cout<<m<<endl;
	return 0;
}
posted @ 2026-01-11 15:51  Godjian  阅读(3)  评论(0)    收藏  举报