2024ICPC区域赛成都站

  • define时间:
#define itn int
#define int long long
#define ind long double
#define yes cout << "Yes"
#define no cout << "No"
#define pii pair<long long, long long>
#define pci pair<char, int>
#define re return;

L. Recover Statistics

签到。

其中 Px 的意义为:数列中恰好有 x% 的数小于等于这个值。

void solve()
{
    cin >> x >> y >> z;
    cout << 100 << '\n';
    for (int i = 1; i <= 50; i++)
    {
        cout << x << ' ';
    }
    for (int i =  51; i <= 95; i++)
    {
        cout << y << ' ';
    }
    for (int i = 96; i <= 99; i++)
    {
        cout << z << ' ';
    }
    cout << z + 1;
}

J. Grand Prix of Ballance

模拟。

看懂题目即可,注意一次只会开放一个关卡,后续的其他指令也只有关于这个关卡才会被响应。

pii sum[N];
set<int> st[N], st1[N];
void solve()
{
    cin >> n >> m >> k;

    for (int i = 1; i <= n; i++)
    {
        fg[i] = 0;
        st[i].clear(); //记录有排名的
        st1[i].clear();//记录放弃的
    }
    for (int i = 1; i <= m; i++)
    {
        sum[i].second = 0; //分数
        sum[i].first = i;  //编号
    }
    int now;//记录当前关卡编号
    while (k--)
    {
        int op;
        cin >> op >> x;
        if (op == 1)
        {
            now = x;
        }
        else if (op == 2)
        {
            cin >> y;
            if (now == y)
            {
                if (st[y].find(x) == st[y].end() && st1[y].find(x) == st1[y].end())
                {
                    sum[x].second += m - st[y].size();
                    st[y].insert(x);
                }
            }
        }
        else
        {
            cin >> y;
            if (now == y)
            {
                if (st[y].find(x) == st[y].end() && st1[y].find(x) == st1[y].end())
                {
                    st1[y].insert(x);
                }
            }
        }
    }
    sort(sum + 1, sum + m + 1, [&](auto x, auto y)
         {
        if(x.second != y.second) return x.second > y.second;
        return x.first < y.first; });
    for (int i = 1; i <= m; i++)
    {
        cout << sum[i].first << ' ' << sum[i].second << '\n';
    }
}

G. Expanding Array

位运算。

void solve() {
    set<int>st;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    for(int i=1;i<=n-1;i++){
        x=a[i],y=a[i+1];
        z=x|y;
        st.insert(x);
        st.insert(y);
        st.insert(z);
        st.insert(x&y);
        st.insert(x^y);
        st.insert(z^x);
        st.insert(y^z);
        st.insert(0);
    }
    cout<<st.size();

}

A. Arrow a Row

构造。

void solve()
{
    cin >> s1;
    num = 0;
    vector<pii> v;
    n = s1.size();
    for (auto i : s1)
    {
        if (i == '-')
        {
            num++;
        }
    }
    cnt = 0;
    if (!num || n < 5)
    {
        cout << "No";
        re;
    }
    if (s1[0] != '>' || s1.substr(s1.size() - 3, 3) != ">>>")
    {
        cout << "No";
        re;
    }

    for (int i = n - 1; i >= 0; i--)
    {
        if (s1[i] == '>')
        {
            cnt++;
        }
        else
        {
            break;
        }
    }
    cout << "Yes ";
    for (int i = cnt; i > 3; i--)
    {
        v.emplace_back(n - 4, 5);
        n--;
    }
    for (int i = 0; i < n - 3; i++)
    {
        if (s1[i] == '>')
        {
            v.emplace_back(i + 1, n - i);
        }
    }
    cout << v.size() << '\n';
    for (auto j : v)
    {
        cout << j.first << ' ' << j.second << '\n';
    }
}

I. Good Partitions

思维。

题意:给定一个数字序列和 \(k\) 次修改,每次修改 \(a[x]=y\),有 \(k+1\) 次询问:

将序列分割为以 \(m\) 为间隔的小段,每小段满足非递减。问 \(m\) 可能的值有多少个。

思路:我们可以考虑如果 \(a[i-1]>a[i]\),说明这个点将作为分割点,放入set。

又发现最后所有分割点应该具有相同的间隔,我们只可能将大段切成小段。

于是我们可以转化题意:

对于第一个出现的分割点,遍历他的因子;只有后续所有分割点都是因子的倍数,才是可能的 \(m\)

vector<int> e[N+5];
void solve()
{
    set<int> st;
    cin >> n >> k;
    fill(b,b+N,0);
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    auto ck = [&]()
    {
        if (st.empty())
        {
            return n;
        }
        ans = 0;
        auto minn = *st.begin();
        for (auto i : e[minn])//遍历第一个分割点的因子
        {
            if (b[1] == b[i])//所有分割点都是该因子的倍数等价于此式
            {
                ans++;
            }
        }
        return ans;
    };
    auto add = [&](int x)
    {
        st.insert(x);
        for (auto j : e[x])
        {
            b[j]++;
        }
    };
    auto sub = [&](int x)
    {
        st.erase(x);
        for (auto j : e[x])
        {
            b[j]--;
        }
    };
    for (int i = 2; i <= n; i++)
    {
        if (a[i - 1] > a[i])
        {
            add(i - 1);
        }
    }
    cout << ck() << '\n';
    while (k--)
    {
        cin >> x >> y;
        if (x > 1 && a[x - 1] > a[x])
        {
            sub(x - 1);
        }
        if (x < n && a[x] > a[x + 1])
        {
            sub(x);
        }
        a[x] = y;
        if (x > 1 && a[x - 1] > a[x])
        {
            add(x - 1);
        }
        if (x < n && a[x] > a[x + 1])
        {
            add(x);
        }
        cout << ck() << '\n';
    }
}

signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    /* solve(); */

    int T;
    T = 1;
    cin >> T;
    for (int i = 1; i <= N; i++)//预处理因子
    {
        for (int j = i; j <= N; j += i)
        {
            e[j].emplace_back(i);
        }
    }
    while (T--)
    {
        solve();
    }

    return 0;
}
posted @ 2025-09-04 22:22  lengling  阅读(120)  评论(0)    收藏  举报