2025CCPC邀请赛(南昌)VP(A,B,C,D,G,H,K,L)

有部分解法不给出思路

A.扭蛋

#include<bits/stdc++.h>
#define endl '\n'
#define fread freopen("C://Users//20321//Desktop//vscode_cpp//in.in", "r", stdin)
#define fout freopen("C://Users//20321//Desktop//vscode_cpp//out.out", "w", stdout)
#define fl cout.flush()

using namespace std;
typedef long long ll;

const ll INF=1e18;
const int N=2e5+5;
const ll mod=1e9+7;

ll t,n,m;
ll a[N];

// ll ksm(ll a, ll b) {
//     ll res = 1;
//     a %= mod;
//     while (b > 0) {
//         if (b & 1)
//             res = res * a % mod;
//         a = a * a % mod;
//         b >>= 1;
//     }
//     return res%mod;
// }

ll k;

void fio(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}

bool check(ll v){
    ll sum=0;
    ll id=0;
    for(int i=1; i<=n; i++){
        sum+=a[i];
        if(sum>=v){
            v-=i;
            id=i;
            break;
        }
    }
    if(v/k>=n-id){
        return true;
    }
    else return false;
}

void solve(){
    cin >> n >> k;
    ll tot=0;
    for(int i=1; i<=n; i++){
        cin >> a[i];
        tot+=a[i];
    }
    sort(a+1,a+1+n,greater<ll>());
    ll l=1,r=tot;
    ll ans=r;
    while(l<=r){
        ll mid=(l+r)/2;
        if(check(mid)){
            ans=min(ans,mid);
            r=mid-1;
        }
        else{
            l=mid+1;
        }
    }
    cout << ans << endl;
}

signed main()
{
	//fread; //?cph??
	fio();
	cin >> t;
	//t=1;
	while(t--){
		solve();
	}
	return 0;
}

B.精神胜利

#include<bits/stdc++.h>
#define endl '\n'
#define fread freopen("C://Users//20321//Desktop//vscode_cpp//in.in", "r", stdin)
#define fout freopen("C://Users//20321//Desktop//vscode_cpp//out.out", "w", stdout)
#define fl cout.flush()

using namespace std;
typedef long long ll;

const ll INF=1e18;
const int N=5005;
const ll mod=1e9+7;


// ll ksm(ll a, ll b) {
//     ll res = 1;
//     a %= mod;
//     while (b > 0) {
//         if (b & 1)
//             res = res * a % mod;
//         a = a * a % mod;
//         b >>= 1;
//     }
//     return res%mod;
// }
const int inf=1000000;
void fio(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
int dis[505][505];
vector<int> ok[N];
void solve(){
	int n,q;
    cin>>n>>q;
    if(n<=500){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(i!=j)dis[i][j]=inf;
                else dis[i][j]=0;
            }
        }
        for(int i=1;i<=n-1;i++){
            string s;
            cin>>s;
            s="#"+s;
            for(int j=1;j<=n-i;j++){
                if(s[j]=='0'){
                    dis[i+j][i]=1;
                }else{
                    dis[i][i+j]=1;
                }
            }
        }
        for(int k=1;k<=n;k++){
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
                }
            }
        }
        // for(int i=1;i<=n;i++){
        //     for(int j=1;j<=n;j++){
        //         cout<<dis[i][j]<<" ";
        //     }
        //     cout<<"\n";
        // }
        for(int i=1;i<=q;i++){
            int a,b;
            cin>>a>>b;
            if(dis[a][b]==inf){
                cout<<"-1\n";
            }else{
                cout<<dis[a][b]-1<<"\n";
            }
        }
    }else{
        for(int i=1;i<=n-1;i++){
            string s;
            cin>>s;
            s="#"+s;
            for(int j=1;j<=n-i;j++){
                if(s[j]=='0'){
                    ok[i+j].push_back(i);
                }else{
                    ok[i].push_back(i+j);
                }
            }
        }
        for(int i=1;i<=q;i++){
            int a,b;
            cin>>a>>b;
            bool k=1;
            for(auto to:ok[a]){
                if(to==b){
                    k=0;
                    break;
                }
            }          
            cout<<k<<"\n";
        }
    }
}

signed main()
{
	// fread; //?cph??
	fio();
	int t=1;
	// cin >> t;
	while(t--){
		solve();
	}
	return 0;
}

C.虫洞

思路:如果我选择的一个[L,R]在x处出现了k次重叠,如果在y处(x<=y)出现了小于等于k次重叠,显然无论是x处线段延申到y或者y是由新的k个线段重叠而来,可以发现,我们仍然可以将线段分配成k组且组内互不相交,那么我们可以把题目理解成寻找标号在[L,R]的线段,使得他们在坐标轴排布后,单点重叠需要小于等于k次,由于这个具有单调性,双指针+区间最值线段树即可解决。

#include<bits/stdc++.h>
#define endl '\n'
#define fread freopen("C://Users//20321//Desktop//vscode_cpp//in.in", "r", stdin)
#define fout freopen("C://Users//20321//Desktop//vscode_cpp//out.out", "w", stdout)
#define fl cout.flush()

using namespace std;
typedef long long ll;

const ll INF=1e18;
const int N=2e5+5;
const ll mod=1e9+7;
const ll maxn=2e5+5;
struct tree {
    ll v,la;
    ll l, r;
}p[maxn << 2];
void build(ll i, ll l, ll r) {
    p[i].l = l, p[i].r = r;
    p[i].v = 0;
    p[i].la=0;
    if (l == r)return;
    build(i << 1, l, l + r >> 1);
    build(i << 1 | 1, (l + r >> 1) + 1, r);
}
void push_down(ll i){
    if(p[i].la){
        p[i<<1].v+=p[i].la;p[i<<1|1].v+=p[i].la;
        p[i<<1].la+=p[i].la;p[i<<1|1].la+=p[i].la;
        p[i].la=0;
    }
}
void update(ll i, ll l,ll r, ll x) {//?
    if (p[i].l==l&&p[i].r==r) {
        p[i].v+=x;
        p[i].la+=x;
        return;
    }
    push_down(i);
    ll mid = p[i].l + p[i].r >> 1;
    if(l<= mid)update(i << 1,l, min(mid,r),x);
    if(r>=mid+1)update(i << 1 | 1, max(l,mid+1),r,x);
    p[i].v = max(p[i << 1].v, p[i << 1 | 1].v);
}
ll query(ll i, ll l, ll r) {
    ll ans = 0;
    if (p[i].l == l && p[i].r == r) {
        return p[i].v;
    }
    push_down(i);
    ll mid = p[i].l + p[i].r >> 1;
    if (l <= mid)ans = max(ans, query(i << 1, l, min(mid, r)));
    if (r >= mid + 1)ans = max(ans, query(i << 1 | 1, max(mid + 1, l), r));
    return ans;
}
void fio(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}

void solve(){
	ll n,k;
    cin>>n>>k;
    vector<pair<ll,ll>>a(n+2);
    for(ll i=1;i<=n;i++){
        auto &[l,r]=a[i];
        cin>>l>>r;
    }
    build(1,1,n);
    deque<ll>que;
    ll ans=0;
    for(ll i=1;i<=n;i++){
        auto [l,r]=a[i];
        que.push_back(i),update(1,l,r,1);
        while(query(1,1,n)>k){
            auto [l1,r1]=a[que.front()];
            update(1,l1,r1,-1);
            que.pop_front();
        }
        ans=max(ans,(ll)que.size());
            //ll u=query(1,1,n);
    }
    cout<<ans<<endl;
}

signed main()
{
	
	fio();
   // fread; //?cph??
    ll t=1;
	cin >> t;
	//t=1;
	while(t--){
		solve();
	}
	return 0;
}

D.挑战图同构

思路:如果边值均为1,那么1-2-3和3-1-2是等价的。那么我们可以发现如果从小到大枚举边连接未连接的点,使得每次G1,G2的点构成的并查集具有相同的对应状态就是YES的条件。这里枚举连通分量然后再枚举边,开了两个并查集,对G1中的连通分量que1按上述枚举方式枚举,每次连同值边,直到值变了再连接G2.注意如果G1没修改,那么在que2中小于等于原值的边也不能产生影响。否则que2中小于原值的边也不能产生影响,然后等值边连接完后得构成和G1相同的并查集。为了保证que2能枚举完,推荐在que1中加个无穷大边,最后跳出即可。每次检测是Co2检测Co1连的边(Co2和Co1分别是G1,G2的并查集),然后Co1检测Co2连接的边,写得可能复杂了?

#pragma GCC optimize(3, "Ofast", "inline", "unroll-loops")   
#include<iostream>
#include<queue>
#include<map>
#include<iomanip>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#include<functional>
#define endl '\n'
#define fread freopen("C://Users//20321//Desktop//vscode_cpp//in.in", "r", stdin)
#define fout freopen("C://Users//20321//Desktop//vscode_cpp//out.out", "w", stdout)
#define fl cout.flush()

using namespace std;
typedef long long ll;

const ll INF = 1e18;
const int N = 2e5 + 5;
const ll mod = 1e9 + 7;
const ll maxn = 2e5 + 5;
void fio() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
struct s {
    ll l, r, v;
    friend bool operator<(const s& a, const s& b) {
        return a.v < b.v;
    };
};
ll find(ll x, vector<ll>& a) {
    if (x == a[x])return x;
    else return a[x] = find(a[x], a);
}
void solve() {
    ll n, m, k;
    cin >> n >> m >> k;
    vector<vector<pair<ll, ll>>>g1(n+2), g2(n+2);
    vector<ll>co1(n + 2, 0), co2(n + 2, 0);
    for (ll i = 1; i <= n; i++)co1[i] = co2[i] = i;
    vector<bool>vi1(n + 2, 0), vi2(n + 2, 0), vi(n + 2, 0);
    for (ll i = 1; i <= m; i++) {
        ll l, r, v;
        cin >> l >> r >> v;
        g1[l].push_back({ r,v });
        g1[r].push_back({ l,v });
    }
    for (ll i = 1; i <= k; i++) {
        ll l, r, v;
        cin >> l >> r >> v;
        g2[l].push_back({ r,v });
        g2[r].push_back({ l,v });
    }

    auto dfs = [&](ll x, auto&& dfs, vector<vector<pair<ll, ll>>>& g, vector<ll>& b, vector<bool>& vis, vector<s>& f)->void {
        vis[x] = 1;
        vi[x] = 1;
        b.push_back(x);
        for (auto& [to, v] : g[x]) {
            if (!vis[to])f.push_back({ to,x,v });
        }
        for (auto& [to, v] : g[x]) {
            if (vis[to])continue;
            dfs(to, dfs, g, b, vis, f);
        }
        };

    auto ck = [&](ll x)->int {
        vector<ll>ls1, ls2;
        vector<s>ls;
        vector<s>que1, que2;
        dfs(x, dfs, g1, ls1, vi1, que1);
        dfs(x, dfs, g2, ls2, vi2, que2);
        sort(ls1.begin(), ls1.end());
        sort(ls2.begin(), ls2.end());
        if (ls1 != ls2)return 0;
        sort(que1.begin(), que1.end());
        sort(que2.begin(), que2.end());
        if(que1.size()==0&&que2.size()==0)return 1;
        else if(que1.size()==0||que2.size()==0)return 0;
        ll l = 0;
        ll cc = que1[0].v;
        bool flag = 0;
        que1.push_back({ 0,7,(ll)1e18 });
        for (ll i = 0; i < que1.size(); i++) {
            auto [x, y, v] = que1[i];
            if (cc == v) {
                ls.push_back(que1[i]);
                ll fx = find(x, co1);
                ll fy = find(y, co1);
                if (fx == fy)continue;
                co1[fx] = fy;
                flag = 1;
            }
            else {
                if (flag == 0) {
                    while (l < que2.size() && que2[l].v <= cc) {
                        auto [x1, y1, v1] = que2[l];
                        l++;
                        if (find(x1, co2) != find(y1, co2))return 0;
                    }
                }
                else {
                    if (l == que2.size())return 0;
                    while(l<que2.size()&&que2[l].v<cc){
                        auto [x1, y1, v1] = que2[l];
                        l++;
                        ll fx = find(x1, co2);
                        ll fy = find(y1, co2);
                        if(fx!=fy)return 0;
                    }
                    while (l < que2.size() && que2[l].v == cc) {
                        auto [x1, y1, v1] = que2[l];
                        l++;
                        ll fx = find(x1, co2);
                        ll fy = find(y1, co2);
                        if (find(x1, co1) != find(y1, co1))return 0;
                        if (fx == fy)continue;
                        co2[fx] = fy;
                    }
                    for (auto [x1, y1, z1] : ls) {
                        if (find(x1, co2) != find(y1, co2))return 0;
                    }
                }
                if (i == que1.size() - 1)break;
                ls.clear();
                flag = 0;
                cc = v;
                ls.push_back(que1[i]);
                ll fx = find(x, co1);
                ll fy = find(y, co1);
                if (fx == fy)continue;
                co1[fx] = fy;
                flag = 1;
            }
        }
        return 1;
        };

    for (ll i = 1; i <= n; i++) {
        if (vi[i])continue;
        if (!ck(i)) {
            cout << "NO" << endl; 
            return;
        }
    }
    cout << "YES" << endl;
}

signed main()
{

    fio();
    // fread; //?cph??
    ll t = 1;
    cin >> t;
    //t=1;
    while (t--) {
        solve();
    }
    return 0;
}

G.玻璃碎晶

#include<bits/stdc++.h>
#define endl '\n'
#define fread freopen("C://Users//20321//Desktop//vscode_cpp//in.in", "r", stdin)
#define fout freopen("C://Users//20321//Desktop//vscode_cpp//out.out", "w", stdout)
#define fl cout.flush()

using namespace std;
typedef long long ll;

const ll INF=1e18;
const int N=2e5+5;
const ll mod=1e9+7;

ll t,n,m;

// ll ksm(ll a, ll b) {
//     ll res = 1;
//     a %= mod;
//     while (b > 0) {
//         if (b & 1)
//             res = res * a % mod;
//         a = a * a % mod;
//         b >>= 1;
//     }
//     return res%mod;
// }

void fio(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}

void solve(){
    cin >> n;
    if(n==1 || n==2 || n==4){
        cout << -1 << endl;
        return;
    }
    if(n%3==0 || n%3==2){
        cout << n/3 << endl;
    }
    else{
        cout << n/3-1 << endl;
    }
}

signed main()
{
	//fread; //?cph??
	fio();
	cin >> t;
	//t=1;
	while(t--){
		solve();
	}
	return 0;
}

H.珍珠链

思路:可想-1的条件是出现\(a_i<i\)。那么我们只需去卡这个边界即可,第i位最多可以等\(a_i-i\)轮,那么我们从后往前维护最小\(a_i-i\),然后边走边卡边界即可

#include<bits/stdc++.h>
#define endl '\n'
#define fread freopen("C://Users//20321//Desktop//vscode_cpp//in.in", "r", stdin)
#define fout freopen("C://Users//20321//Desktop//vscode_cpp//out.out", "w", stdout)
#define fl cout.flush()

using namespace std;
typedef long long ll;

const ll INF=1e18;
const int N=2e5+5;
const ll mod=1e9+7;

//ll t,n,m;

// ll ksm(ll a, ll b) {
//     ll res = 1;
//     a %= mod;
//     while (b > 0) {
//         if (b & 1)
//             res = res * a % mod;
//         a = a * a % mod;
//         b >>= 1;
//     }
//     return res%mod;
// }

void fio(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}

void solve(){
	ll n;
	cin>>n;
	vector<ll>a(n+2);
	bool flag=0;
	for(ll i=1;i<=n;i++){
		cin>>a[i];
		if(a[i]<i)flag=1;
	}
	if(flag){
		cout<<-1<<endl;
		return ;
	}
	vector<ll>pre(n+2,1e18);
	for(ll i=n;i>=1;i--){
        pre[i]=min(pre[i+1],a[i]-i);
	}
    ll op=1;
    ll ans=0;
    ll now=0;
    ll wait=0;
    for(ll i=1;i<=n;i++){
        ll kk=pre[i]-wait;
        ll u=min(now,kk);
        wait+=u;
        now-=u;
        ans+=u;
        op+=u;
        now+=a[i]-op;
        op++;
        ans++;
     //  cout<<now<<" "<<ans<<endl;
    }
    ans+=now;
    cout<<ans<<endl;
}

signed main()
{
	
	fio();
   // fread; //?cph??
    ll t=1;
	cin >> t;
	//t=1;
	while(t--){
		solve();
	}
	return 0;
}

k.不许偷吃

思路:注意总和为4的倍数且现在说的数是模4得出的数。0随便放,3和1匹配,如果3多,那就3 2 2 匹配(一定出现偶数个3),如果1多,那就2 1 1匹配(一定出现偶数次1),然后剩下就直接放剩下的2即可。

这里为了方便,在上述构造方式构造完了后,把可能剩下的数加到数组里了,最后线性检测正确性即可

#include<bits/stdc++.h>
#define endl '\n'
#define fread freopen("C://Users//20321//Desktop//vscode_cpp//in.in", "r", stdin)
#define fout freopen("C://Users//20321//Desktop//vscode_cpp//out.out", "w", stdout)
#define fl cout.flush()

using namespace std;
typedef long long ll;

const ll INF=1e18;
const int N=2e5+5;
const ll mod=1e9+7;

//ll t,n,m;

// ll ksm(ll a, ll b) {
//     ll res = 1;
//     a %= mod;
//     while (b > 0) {
//         if (b & 1)
//             res = res * a % mod;
//         a = a * a % mod;
//         b >>= 1;
//     }
//     return res%mod;
// }

void fio(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}

void solve(){
	ll n;
    cin>>n;
    vector<ll>a(n+2);
    vector<vector<ll>>sz(5);
    for(ll i=1;i<=n;i++){
        cin>>a[i];
        ll u=a[i]%4;
        sz[u].push_back(i);
    }
    vector<ll>ans;
    for(auto j:sz[0])ans.push_back(j);
    ll l3=0,l1=0,l2=0;
    while(l3<sz[3].size()&&l1<sz[1].size()){//3 1
        ans.push_back(sz[3][l3]);
        ans.push_back(sz[1][l1]);
        l3++;
        l1++;
    }
    while(l3+1<sz[3].size()&&l2<sz[2].size()){// 3 3 2
        ans.push_back(sz[3][l3]);
        l3++;
        ans.push_back(sz[3][l3]);
        l3++;
        ans.push_back(sz[2][l2]);
        l2++;
    }
    while(l1+1<sz[1].size()&&l2<sz[2].size()){// 2 1 1 
        ans.push_back(sz[2][l2]);
        l2++;
        ans.push_back(sz[1][l1]);
        l1++;
        ans.push_back(sz[1][l1]);
        l1++;
    }
    while(l2<sz[2].size()){
        ans.push_back(sz[2][l2]);
        l2++;   
    }
    while(l1<sz[1].size()){
        ans.push_back(sz[1][l1]);
        l1++;
    }
    while(l3<sz[3].size()){
        ans.push_back(sz[3][l3]);
        l3++;
    }
    ll flag=0;
    ll sum=0;
    for(auto j:ans){
        sum+=a[j];
        sum%=4;
        if(sum==1)flag=1;
    }
    if(flag)cout<<-1<<endl;
    else {
        for(auto j:ans)cout<<j<<" ";
        cout<<endl;
    }
}

signed main()
{
	
	fio();
   // fread; //?cph??
    ll t=1;
	cin >> t;
	//t=1;
	while(t--){
		solve();
	}
	return 0;
}

L.羽球比赛

#include<bits/stdc++.h>
#define endl '\n'
#define fread freopen("C://Users//20321//Desktop//vscode_cpp//in.in", "r", stdin)
#define fout freopen("C://Users//20321//Desktop//vscode_cpp//out.out", "w", stdout)
#define fl cout.flush()

using namespace std;
typedef long long ll;

const ll INF=1e18;
const int N=2e5+5;
const ll mod=1e9+7;

ll t,n,m;

// ll ksm(ll a, ll b) {
//     ll res = 1;
//     a %= mod;
//     while (b > 0) {
//         if (b & 1)
//             res = res * a % mod;
//         a = a * a % mod;
//         b >>= 1;
//     }
//     return res%mod;
// }

void fio(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}

void solve(){
    ll a,b;
    cin >> a >> b;
    if((a>=21 && a-b>=2) || (a==30)){
        cout << "Alice" << endl;
        return;
    }
    if((b>=21 && b-a>=2) || (b==30)){
        cout  << "Bob" << endl;
        return;
    }
    cout << "Underway" << endl;
    return;
}

signed main()
{
	//fread; //?cph??
	fio();
	//cin >> t;
	t=1;
	while(t--){
		solve();
	}
	return 0;
}
posted @ 2025-09-19 15:44  长皆  阅读(41)  评论(0)    收藏  举报