The 2025 ICPC Latin America Championship2025/3/26组队vp记录

比赛链接:https://codeforces.com/gym/105789

A.Ananna

思路:如果从端点去枚举一条路构成回文串会TLE,所以想着枚举中心向着两边扩散,如果两个端点构成了回文串(最多n*n对),那么他们扩散就只要看字符相同即可,所以建正边和反边。先把所有边塞进队列,然后把每个
点作为点对也塞进队列(比如2——3——4情况需要这样扩散),左点跑反边,右边跑正边即可。

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#define ll                            long long 
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans;
}
ll gcd(ll x, ll y)
{
    if (y == 0)
        return x;
    else
        return gcd(y, x % y);
}
inline ll read()
{
    register ll x = 0, f = 1;
    char c = getchar();
    while (c < '0' || c>'9')
    {
        if (c == '-') f = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9')
    {
        x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速
        c = getchar();
    }
    return x * f;
}
void fio()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
struct ss
{
    ll l, r;
    friend bool operator<(const ss& a, const ss& b)
    {
        return a.l < b.l;
    }
};
bool vis[5005][5005], dd[5005][5005];
vector<pair<ll,char>>g1[5005];
vector<pair<ll,char>>g2[5005];
int main()
{
    fio();
    ll n, m;
    cin >> n >> m;
    queue<ss>f;
    map<pair<ll,pair<ll,char>>,bool>mp;
    for (ll i = 1; i <= m; i++)
    {
        ll l, r;
        char k;
        cin >> l >> r >> k;
        if(mp[{l,{r,k}}]==1)continue;
        else mp[{l,{r,k}}]=1;
        g1[l].push_back({r,k});
        g2[r].push_back({l,k});
        if (l != r&&dd[l][r]==0)
        {
            f.push({l,r});
            dd[l][r]=1;
        }
    }
    for(ll j=1;j<=n;j++)
    {
        f.push({j,j});
        dd[j][j]=1;
    }
    ll ans = 0;
    while (!f.empty())
    {
        ll l = f.front().l;
        ll r = f.front().r;
        f.pop();
        if (vis[l][r])continue;
        vis[l][r] = 1;
        if(l!=r){
            ans++;
        }
        for (auto j : g2[l])
        {
            for (auto k : g1[r])
            {
                if (j.first == k.first || vis[j.first][k.first] || j.second!=k.second || dd[j.first][k.first])continue;
                f.push({ j.first,k.first }), dd[j.first][k.first] = 1;
            }
        }
    }
    cout << ans << endl;
}

C. Coatless in Yakutsk

思路:队友写的,二分

#include <iostream>
#include <algorithm>
#include <queue>
#include <deque>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#include <numeric>
#define endl '\n'
#define ll long long
using namespace std;
const ll N=2e5+5;
int c,n;
int a[N];
bool check(int x){
	int day=0;
	for(int i=1;i<=n;i++){
		if(day>c)return 0;
		if(a[i]>=x){
			day=0;
		}else{	
			day++;
		}
	}
	if(day>c)return 0;
	return 1;
}
void eachT()
{
	cin>>c>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	int l=-50,r=50,mid,ans;
	while(l<=r){
		mid=(l+r)/2;
		if(check(mid)){
			l=mid+1;
			ans=mid;
		}else{
			r=mid-1;
		}
	}
	cout<<ans<<"\n";
}



int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	ll T=1;
	// cin>>T;
	while(T--)
		eachT();
}

G. Game of Pieces

思路:要么动态开点线段树或者离散化线段树,要么set维护

//#注意如果多组样例,记得手动更新p数组,然后rt归位,在更新和询问时query都是必须判断有没开过点的的,只需q*logn的空间
#include<iostream>
#define ll long long 
using namespace std;
const ll maxn = 5e6 + 10;
struct s
{
    ll l = -1, r = -1;
    ll v, v1=0,v2=0,la = -1;
}p[maxn << 2];
ll rt = -1;
ll root = -1;
void push_down(ll pos, ll l, ll r)
{
    if (p[pos].la >= 0)
    {
        if (p[pos].l == -1)p[pos].l = ++rt;
        if (p[pos].r == -1)p[pos].r = ++rt;
        ll mid = (l + r) >> 1;
        // p[p[pos].l].v += (mid - l + 1) * p[pos].la;//区间值
        // p[p[pos].r].v += (r - mid) * p[pos].la;//区间值
        p[p[pos].l].v1 += p[pos].la;
        p[p[pos].r].v1 += p[pos].la;
        p[p[pos].l].v2 += p[pos].la;
        p[p[pos].r].v2 += p[pos].la;
        p[pos].v1 = max(p[p[pos].l].v1, p[p[pos].r].v1);
        p[pos].v2 = min(p[p[pos].l].v2, p[p[pos].r].v2);
        p[p[pos].l].la = (p[p[pos].l].la == -1 ? p[pos].la : p[pos].la + p[p[pos].l].la);
        p[p[pos].r].la = (p[p[pos].r].la == -1 ? p[pos].la : p[pos].la + p[p[pos].r].la);
        p[pos].la = -1;
    }
}
void update(ll& pos, ll l1, ll r1, ll l, ll r, ll v)
{
    if (pos < 0)pos = ++rt;
    if (l1 == l && r1 == r)
    {
        //p[pos].v += (r - l + 1) * v;
        p[pos].la = (p[pos].la == -1 ? v : p[pos].la + v);
        p[pos].v1+=v;
        p[pos].v2+=v;
        return;
    }
    push_down(pos, l1, r1);
    ll mid = (l1 + r1) >> 1;
    if (l <= mid)
        update(p[pos].l, l1, mid, l, min(r, mid), v);
    if (r >= mid + 1)
        update(p[pos].r, mid + 1, r1, max(mid + 1, l), r, v);
   // p[pos].v = (p[pos].l >= 0 ? p[p[pos].l].v : 0) + (p[pos].r >= 0 ? p[p[pos].r].v : 0);
    p[pos].v1 = max((p[pos].l >= 0 ? p[p[pos].l].v1 : 0), (p[pos].r >= 0 ? p[p[pos].r].v1 : 0));
    p[pos].v2 = min((p[pos].l >= 0 ? p[p[pos].l].v2 : 0), (p[pos].r >= 0 ? p[p[pos].r].v2 : 0));
}
pair<ll,ll> query(ll& pos, ll l1, ll r1, ll l, ll r)
{
    pair<ll, ll> ans = { 0,1e18 };
    if (pos < 0)pos = ++rt;
    if (l1 == l && r1 == r)
    {
        return {p[pos].v1,p[pos].v2};
    }
    push_down(pos, l1, r1);
    ll mid = (l1 + r1) >> 1;
    pair<ll, ll>z;
    if (l <= mid)
    {
        z = query(p[pos].l, l1, mid, l, min(r, mid));
        ans.first =max(z.first,ans.first);
        ans.second=min(ans.second, z.second);
    }
    if (r >= mid + 1)
    {
        z = query(p[pos].r, mid + 1, r1, max(mid + 1, l), r);
        ans.first =max(z.first,ans.first);
        ans.second=min(ans.second, z.second);
    }
    return ans;
}
int main()
{
    ll n;
    cin >> n;
    ll yb = 2e18;
    while (n--)
    {
        char f;
        ll l, r;
        cin >> f >> l >> r;
        if (f == '|')
        {
            cout << "S";
            update(root, 1, yb, r, r, l);
        }
        else
        {
            pair<ll, ll>j = query(root, 1, yb, r, r + l - 1);
            if (j.first!=j.second)
            {
                cout << "U";
            }
            else
            {
                cout << "S";
                update(root, 1, yb, r, r + l - 1, 1);
            }
        }
    }
    cout << endl;
}

K. Keep Fighting

思路:特判掉特殊情况后,先暴力掉所有牌用掉的情况,最后枚举单独去三重循环枚举所有可能即可得出,记得做个最大数限制

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#define ll                            long long 
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans;
}
ll gcd(ll x, ll y)
{
    if (y == 0)
        return x;
    else
        return gcd(y, x % y);
}
inline ll read()
{
    register ll x = 0, f = 1;
    char c = getchar();
    while (c < '0' || c>'9')
    {
        if (c == '-') f = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9')
    {
        x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速
        c = getchar();
    }
    return x * f;
}
void fio()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
struct ss
{
    ll l, r;
    friend bool operator<(const ss& a, const ss& b)
    {
        return a.l < b.l;
    }
};
int main()
{
    fio();
    ll n,p,k;
    cin>>n>>p>>k;
    ll cnt=0;
    vector<ll>k1,k2;
    for(ll i=1;i<=n;i++)
    {
        char f;
        ll x;
        cin>>f;
        if(f=='!')cnt++;
        else 
        {
            cin>>x;
            if(f=='*'&&x==1)continue;
            if(f=='*')k1.push_back(x);
            else k2.push_back(x);
        }
    }
    sort(k1.begin(),k1.end(),greater<>());//mul
    sort(k2.begin(),k2.end(),greater<>());//add
    //ll ans=0;
    if(cnt==0||(p==0&&k2.size()==0))
    {
        cout<<"*"<<endl;
        return 0;
    }
    else if(p&&(k1.size()==0&&k2.size()==0))
    {
        ll f=k/p+(k%p>0);//cnt个数
        ll zq=f/cnt;
        if(f%cnt==0)zq--;
        zq=max(zq,(ll)0);
        cout<<f+(zq)*(n-cnt)<<endl;
        return 0;
    }
    ll ad=0;
    for(auto x:k2){
        ad+=x;
    }
    function<bool(ll)>ck=[&](ll x)
    {
        if(x>=k)
        {
            return 1;
        }
        else return 0;
    };
    ll ans=0;//轮
    ll att=p;
    while(1)
    {
        ll cm=p;//attack
        ll f=att+ad;//res
        f=min(1000000001ll,f);
        ll pd=0;
        if(ck(f*cnt)){
            pd=1;
        }
        for(auto j:k1){
            if(ck(f*cnt)){
                pd=1;
                break;
            }else{
                f=min(1000000001ll,f);
                f*=j;
                f=min(1000000001ll,f);
            }
        }
        if(ck(f*cnt)){
            pd=1;
        }
        if(pd){
            break;
        }else{
            att=f;
            ans+=n;
            k-=att*cnt;
        }
    }
    att=min(1000000001ll,att);
    ll op=n;
    for(ll l=1;l<=cnt;l++){
        ll f=1;
        for(ll i=0;i<=k1.size();i++){
            ll sum=0;
            if(i!=0)
            {
                f=min(1000000001ll,f);
                f*=k1[i-1];
                f=min(1000000001ll,f);
            }
            for(ll j=0;j<=k2.size();j++){
                if(i+l+j>=op)continue;
                if(j!=0){
                    sum+=k2[j-1];
                    sum=min(sum,1000000001ll);
                }
                if(i+j+l<op){
                    if(ck(min((att+sum)*f,1000000001ll)*l)){
                        op=min(op,i+j+l);
                    }
                }
            }
        }
    }
    ans+=op;
    cout<<ans<<"\n";
}

L. LED Counter

思路:对于每个字符串枚举0到9即可.0到9的字符串第一个样例有给出

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<functional>
#include<stack>
#include<unordered_map>
#include<string>
#define ll                            long long 
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
//const ll p=rnd()%mod;
#define F first
#define S second
// tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>;find_by_order(k),找第k位(从小到大)的数字,order_of_key(x),x的排名
ll ksm(ll x, ll y)
{
    ll ans = 1;
    x %= mod;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans;
}
ll gcd(ll x, ll y)
{
    if (y == 0)
        return x;
    else
        return gcd(y, x % y);
}
inline ll read()
{
    register ll x = 0, f = 1;
    char c = getchar();
    while (c < '0' || c>'9')
    {
        if (c == '-') f = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9')
    {
        x = (x << 3) + (x << 1) + (c ^ 48); //等价于x*10+c-48,使用位运算加速
        c = getchar();
    }
    return x * f;
}
void fio()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
struct ss
{
    ll l, r;
    friend bool operator<(const ss& a, const ss& b)
    {
        return a.l < b.l;
    }
};
string e[20] = { "GGGgGGG","gggggGG","gGGGGGg","ggGGGGG","GggGgGG","GgGGGgG","GGGGGgG","ggGggGG","GGGGGGG","GgGGGGG" };
int main()
{
    fio();
    ll n;
    cin >> n;
    //cout<<e[1]<<endl;
    while (n--)
    {
        string f;
        cin >> f;
        ll cnt = 0;
        ll ok = 0;
        for (ll j = 0; j <= 9; j++)
        {
            ll pd = 0;
            for (ll i = 0; i < f.size(); i++)
            {
                if (e[j][i] == f[i])continue;
                else if (f[i] == 'g' || f[i] == 'G')
                {
                    pd = 2;
                    break;
                }
                else if (f[i] == '+' || f[i] == '-')
                {
                    pd = 1;
                }
            }
            if (pd == 0||pd==1)cnt = j;
            if (pd == 1)ok++;
        }
        if (ok >= 2)
            cout << "*";
        else cout << cnt;

    }
    cout << endl;
    return 0;
}
posted @ 2025-03-27 13:53  长皆  阅读(191)  评论(0)    收藏  举报