Codeforces Round 975 (Div. 2)

传送门:https://codeforces.com/contest/2019

B. All Pairs Segments

题意:

首先样例解释一下:

一共有:[1,2],[1,3],[1,5],[1,6],[1,7],[2,3],[2,5],[2,6],[2,7],[3,5],[3,6],[3,7],[5,6],[5,7],[6,7]

点 1,7 在5个线段中包含,点2,4,6在9个线段中包含,点3,5在11个线段中包含

所以查询 5 时,输出2,查询9时,输出3 ...

思路:

                  1             2           3          5           6           7           假设一共有 n 个数

            

在 i 的下标中 左边一共有 i - 1 个数 ,右边有 n - i + 1,相互组合有 ( i - 1 ) * ( n - i + 1 )的贡献

并且 i 可以和右边的数组合 ,一共有 n - i 个贡献

如果没有出现在数组中,比如说 4 ,左边可以有 i - 1 个数,右边有 ( n - i + 1 ) 可以组合,所以有

( i - 1 ) * ( n - i + 1 ) 

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve()
{
    int n , q;cin >> n >> q;
    vector<int> a(n + 1);
    for( int i = 1; i <= n; i++) cin >> a[i];
    map<int,int> mp;
    for( int i = 1; i <= n; i++)
    {
        mp[( i - 1 ) * ( n - i + 1 ) + n - i ]++;
        if( i > 1 )mp[(i - 1) * ( n - i + 1 )] += ( a[i] - a[i-1] - 1 );
    }
    while(q--)
    {
        int x; cin >> x;
        cout << mp[x] << " ";
    }
    cout << endl;
}
signed main()
{
    int tt; cin >> tt;
    while(tt--)solve();
    return 0;
}

  C. Cards Partition

题意:

思路:

假设 mx 时 数组 a 的最大值,sum 是数组 a 的总和

假设牌的大小为  x ,所有牌的数量为 x * mx,但是还有一种可能 ( sum + x - 1 ) / x * x

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
void solve()
{
    int n , k ; cin >> n >> k;
    vector<int> a(n + 1);
    for( int i = 1; i <= n; i++) cin >> a[i];
    int sum = 0; int mx = 0;
    for( int i = 1 ; i <= n; i++)
    {
        sum += a[i]; mx = max( mx , a[i] );
    }
    int ans = 1;
    for( int i = 1 ; i <= n; i++)
    {
        int temp = max( mx * i , ( sum + i - 1 ) / i * i ) ;
        if( temp <= sum + k ) ans = max( ans , i );
    }
    cout << ans << endl;
}
signed main()
{
    int tt; cin >> tt;
    while(tt--)solve();
    return 0;
}

E. Tree Pruning

题意:

思路:(拓扑排序)

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 5e5 + 10;
int h[N], e[2 * N], ne[2 * N], idx;
int Size[N];
queue<int> que;
int leaf[N];
vector<int> dep[N];
bool vis[N]; int sum;
int deg[N];
void add(int a, int  b)
{
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx++;
}
void dfs(int u, int fa, int depth)
{
    Size[u] = 1;
    dep[depth].push_back(u);
    for (int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (j == fa)continue;
        dfs(j, u , depth + 1 );
        Size[u] += Size[j];
    }
    if (Size[u] == 1) {
        leaf[u] = 1;
    }
}
void topsort()
{
    while (que.size())
    {
        int x = que.front();
        que.pop();
        if (vis[x]) continue;
        vis[x] = true;
        sum++;
        for (int i = h[x]; i != -1; i = ne[i])
        {
            int j = e[i];
            if (j == 1) continue;
            if (--deg[j] <= 1)que.push(j);
        }
    }
}
void solve()
{
    int n; cin >> n;
    sum = 0; idx = 0;
    while (que.size())que.pop();
    for (int i = 0; i <= n; i++)
    {
        leaf[i] = Size[i] = deg[i] = 0;
        vis[i] = false;
        h[i] = -1;
        dep[i].clear();
    }
 
    for (int i = 0; i < n - 1; i++)
    {
        int a, b; cin >> a >> b;
        add(a, b); add(b, a);
        deg[a]++; deg[b]++;
    }
    dfs(1, -1, 0);
    int ans = 2e18;
    for (int i = 1; i < n; i++)
    {
        int res = 0;
        for (auto e : dep[i])
        {
            res += Size[e] - 1;
        }
        ans = min(ans, res + sum);
        for (auto e : dep[i])
        {
            if (leaf[e])
            {
                que.push(e);
            }
        }
        topsort();
    }
    cout << ans << endl;
}
signed main()
{
    int tt; cin >> tt;
    while (tt--)solve();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值