首页 > 其他分享 >秦皇岛2020CCPC补题

秦皇岛2020CCPC补题

时间:2022-11-19 21:11:26浏览次数:82  
标签:秦皇岛 int ll 2020CCPC 补题 using rep se define

秦皇岛2020CCPC A,E,F,G,I,K

A. A Greeting from Qinhuangdao

知识点:简单题
复杂度:\(O(logn)\)

#include<bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for(int i=l,_##i=r;i<=_##i;i++)
#define per(i,r,l) for(int i=r,_##i=l;i>=_##i;i--)
#define ll long long
#define fi first
#define se second
template<class T> using vc = vector<T>;

void solve()
{
    ll n, m;
    cin >> n >> m;
    ll f = n * (n - 1);
    ll g = (m + n) * (m + n - 1);
    ll gc = __gcd(f, g);
    f /= gc;
    g /= gc;
    cout << f << '/' << g << endl;
}

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0);
    int T = 1;
    cin >> T;
    rep(i, 1, T)
    {
        cout << "Case #" << i << ": ";
        solve();
    }
}

E. Exam Results

知识点:贪心
复杂度:\(O(nlogn+n)\)

这题我很快就有了思路,但是只是在脑海中过了一遍,其实少考虑了一些情况,所以直接WA了一发
然后debug时看到一个变量爆 \(int\) 了,以为是这里错了,又WA一发,
最后还是在队友的帮助下考虑到了错误的情况,属实不应该交的那么快

我们将所有的分数和对应的人放在一起,按分数为权值排序,然后枚举最大值,
此时我们能得到及格线 \(p\%*max\) 用双指针就能快速得到有多少个人及格,
需要注意的是及格线 \(p\%*max\) 要上取整,并且枚举的最大值要合法[1]


#include<bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for(int i=l,_##i=r;i<=_##i;i++)
#define per(i,r,l) for(int i=r,_##i=l;i>=_##i;i--)
#define ll long long
#define fi first
#define se second
#define int ll
#define pii pair<int,int>
#define pll pair<ll,ll>
template<class T> using vc = vector<T>;
template<class T> using vvc = vc<vc<T>>;

const int N = 2e5 + 5;

pll s[N * 2];

void solve()
{
    int n, p;
    cin >> n >> p;
    vc<int> st(n + 1), st2(n + 1);
    rep(i, 1, n)
    {
        ll a, b; cin >> a >> b;
        s[i * 2 - 1] = { a,i };
        s[i * 2] = { b,i };
    }
    sort(s + 1, s + n + n + 1);
    int cnt = 0, ans = 0, tmp = 0;
    ll L = 1, fx;
    rep(i, 1, n * 2)
    {
        fx = s[i].fi * p;
        if (st2[s[i].se]++ == 0) tmp++;
        if (st[s[i].se]++ == 0) cnt++;
        while (s[L].fi * 100 < fx)
        {
            if (--st[s[L].se] == 0) cnt--;
            L++;
        }
        if(tmp == n) ans = max(ans, cnt);
    }
    cout << ans << endl;
}

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0);
    int T = 1;
    cin >> T;
    rep(i, 1, T)
    {
        cout << "Case #" << i << ": ";
        solve();
    }
}

F. Friendly Group

知识点:并查集
复杂度:\(O(n)\)

这题是队友A的,但是由于我少清空了w数组WA了一发
我真该死啊.jpg

我们观察,当一个朋友关系连接两个连通块时,不看该边时,这两个连通块至少是两颗树,所以当我让这两个连通块连接时,重新选择连通块时,不会让这两个连通块的答案更少[2],所以每一条边都必连,然后枚举连通块判读是否选取即可


#include<bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for(int i=l,_##i=r;i<=_##i;i++)
#define per(i,r,l) for(int i=r,_##i=l;i>=_##i;i--)
#define ll long long
#define fi first
#define se second
#define pii pair<int,int>
#define pll pair<ll,ll>
template<class T> using vc = vector<T>;
template<class T> using vvc = vc<vc<T>>;

const int N = 3e5 + 5;


int f[N], w[N], sz[N];
void init(int n)
{
    rep(i, 0, n) f[i] = i, sz[i] = 1, w[i] = 0;
}

int find(int u)
{
    if (u == f[u]) return u;
    return f[u] = find(f[u]);
}

void unite(int u, int v)
{
    int fu = find(u), fv = find(v);
    if (fu == fv) w[fu]++;
    else
    {
        w[fv] += w[fu] + 1;
        sz[fv] += sz[fu];
        f[fu] = fv;
    }
}

void solve()
{
    int n, m;
    cin >> n >> m;
    init(n);
    rep(i, 1, m)
    {
        int u, v;
        cin >> u >> v;
        unite(u, v);
    }
    ll ans = 0;
    rep(i, 1, n) if (find(i) == i)
    {
        if (w[i] > sz[i]) ans += w[i] - sz[i];
    }
    cout << ans << endl;
}

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0);
    int T = 1;
    cin >> T;
    rep(i, 1, T)
    {
        cout << "Case #" << i << ": ";
        solve();
    }
}

G. Good Number

知识点:简单题
复杂度:\(O(log^2n)\)

这题有点小恶心,注意判断边界即可


#include<bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for(int i=l,_##i=r;i<=_##i;i++)
#define per(i,r,l) for(int i=r,_##i=l;i>=_##i;i--)
#define ll long long
#define fi first
#define se second
#define int ll
#define pii pair<int,int>
template<class T> using vc = vector<T>;
template<class T> using vvc = vc<vc<T>>;

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

ll ksm(ll x, int n)
{
    ll ret = 1;
    while (n)
    {
        if (n & 1) ret = ret * x;
        n >>= 1;
        x = x * x % mod;
    }
    return ret;
}

void solve()
{
    int n, k;
    cin >> n >> k;
    if (k == 1) cout << n << endl;
    else
    {
        ll x = (ll)pow(2, log2(n) / k), ans = 0;
        rep(i, 1, x)
        {
            if (i == x) ans += (n - ksm(i, k)) / i + 1;
            else ans += (ksm(i + 1, k) - ksm(i, k) - 1) / i + 1;
        }
        cout << ans << endl;
    }
}

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0);
    int T = 1;
    cin >> T;
    rep(i, 1, T)
    {
        cout << "Case #" << i << ": ";
        solve();
    }
}

I. Interstellar Hunter

知识点:线性代数
复杂度:\(O(Qlog(x+y))\)

只要能想到题解中的 任意时刻,能到达的点集可使用两个基向量表示,该题就很简单了
简单模拟下,乱搞就过了,可以让其中一个基向量平行与x轴或者y轴,可以减少很多情况


#include<bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for(int i=l,_##i=r;i<=_##i;i++)
#define per(i,r,l) for(int i=r,_##i=l;i>=_##i;i--)
#define ll long long
#define fi first
#define se second
#define pii pair<int,int>
#define pll pair<ll,ll>
template<class T> using vc = vector<T>;
template<class T> using vvc = vc<vc<T>>;

void solve()
{
    int n; cin >> n;
    pll a = { 0,0 }, b = { 0,0 };
    ll ans(0);
    rep(i, 1, n)
    {
        ll op, x, y, w;
        cin >> op >> x >> y;
        if (op == 1) // 操作1
        {
            while (x)
            {
                ll d = a.fi / x;
                a.fi -= d * x; a.se -= d * y;
                swap(x, a.fi); swap(y, a.se);
            }
            if (y) b.se = __gcd(b.se, abs(y));
            if (b.se) a.se %= b.se;
        }
        else // 操作2
        {
            cin >> w;
            if (a.fi)
            {
                ll d = x / a.fi;
                x -= d * a.fi; y -= d * a.se;
            }
            if (b.se) y %= b.se;
            if (!x && !y) ans += w;
        }
    }
    cout << ans << endl;
}

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0);
    int T = 1;
    cin >> T;
    rep(i, 1, T)
    {
        cout << "Case #" << i << ": ";
        solve();
    }
}

K. Kingdom's Power

知识点:树形dp
复杂度:\(O(nlogn)\)

头一次被卡常,2s时限,1800ms过的,一开始使用vector开空间有个小常数T了

对于每一个点来说,我们按照子树的最大深度进行排序,
除了去第一颗子树的士兵一定是从根节点来的,
否则我们需要考虑去当前子树的士兵是从根节点来的还是上一颗子树的最大深度来的
简单的都不像树形dp,有点像套着树形dp的贪心


#include<bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for(int i=l,_##i=r;i<=_##i;i++)
#define per(i,r,l) for(int i=r,_##i=l;i>=_##i;i--)
#define ll long long
#define fi first
#define se second
#define pii pair<int,int>
#define pll pair<ll,ll>
#define int ll
template<class T> using vc = vector<T>;
template<class T> using vvc = vc<vc<T>>;

const int N = 1e6 + 5;

vc<int> h[N];
int len[N], d[N];

void dfs(int u)
{
    for (auto v : h[u])
    {
        d[v] = d[u] + 1;
        dfs(v);
        len[u] = max(len[u], len[v] + 1);
    }
}

bool cmp(int a, int b) { return len[a] < len[b]; }

ll ans = 0;
void dfs2(int u)
{
    sort(h[u].begin(), h[u].end(), cmp);
    int lim = h[u].size();
    if (lim) dfs2(h[u][0]);
    rep(i, 1, lim - 1)
    {
        ans += min(d[u], len[h[u][i - 1]] + 1);
        dfs2(h[u][i]);
    }
}

void solve()
{
    int n; cin >> n;
    rep(i, 1, n)
    {
        h[i].clear();
        len[i] = d[i] = 0;
    }
    ans = n - 1;
    rep(i, 2, n)
    {
        int f; cin >> f;
        h[f].push_back(i);
    }
    dfs(1);
    dfs2(1);
    cout << ans << endl;
}

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0);
    int T = 1;
    cin >> T;
    rep(i, 1, T)
    {
        cout << "Case #" << i << ": ";
        solve();
    }
}

  1. 当一个人的两个分数都大于此时的最大值时,该最大值不合法 ↩︎

  2. 如果另一个连通块是树(树有n个点,n-1条边),则该连通块的权值会+1+(n-1)-n,如果有更多的边时,答案会更优 ↩︎

标签:秦皇岛,int,ll,2020CCPC,补题,using,rep,se,define
From: https://www.cnblogs.com/lunasama/p/16907081.html

相关文章

  • Atcoder补题计划
    11.17AtCoderRegularContest151知识点:A:简单题B:计数,并查集补题传送门......
  • AtCoder Regular Contest 151补题
    AtCoderRegularContest151A.EqualHammingDistances简单题,注意下答案需要字典序最小即可#include<bits/stdc++.h>usingnamespacestd;#definerep(i,l,r)for(......
  • 【补题】The 2022 SDUT Summer Trials
    比赛链接The2022SDUTSummerTrialsA.Ginger'snumber样例恶臭(恼)签到题简单分解因数就会发现要求的就是\(gcd\),直接算即可,时间复杂度\(\Theta(Tlog(max(x,y)))\)......
  • 绵阳2020CCPC补题
    绵阳2020CCPCD,K,J,L,GD.DefusetheBombs知识点:二分答案复杂度:\(O(nlogn+log^2n)\)vp时我猜了一个结论,验了几个样例就写了,喜提WA3然后队友写了二分答案复杂度\(O(......
  • codeforces补题计划
    11.15CodeforcesRound#833(Div.2)知识点:D:高位和对低位无影响E:笛卡尔树上dp补题传送门......
  • Codeforces Round #833 (Div. 2)补题
    CodeforcesRound#833(Div.2)D.ConstructOR知识点:高位和对低位无影响一开始以为和广州的M一样,是数位dp,后来发现只要找到一个就行果然无论什么时候都要看清题目......
  • 【补题】第 46 届 ICPC EC Final
    比赛题目:第46届ICPCECFinal(正式赛)榜单A.DFSOrder签到题容易发现对于一个点,它的最小位置就是从根走一条链直接到它,最大位置就是除了它的子树,其它全已经走过了。......
  • 广州2022CCPC补题
    IInfection知识点:树上背包第一次写树上背包的题目,没想到就是在区域赛中神奇的是树上背包的复杂度,看起来是\(O(n^3)\),但是实际计算只有\(O(n^2)\)学会树上背包后可......
  • Codeforces Round #786 (Div. 3) 补题记录
    小结:A,B,F切,C没写1ll对照样例才发现,E,G对照样例过,D对照样例+看了其他人代码(主要急于看后面的题,能调出来的但偷懒了。CF1674ANumberTransformation考虑若\(y\)......
  • CCPC2022威海补题
    K看完题之后思路是很自然的:对于每个要求,就转化成对于l和r的限制。原本被题目解释干扰了,纠结了一下区间长度的限制觉得很复杂;后来发现只要l和r合法,区间长度就合法,所以对于1......