其他分享
首页 > 其他分享> > Codeforces Round #724 (Div. 2) A~D题解

Codeforces Round #724 (Div. 2) A~D题解

作者:互联网

本场链接:Codeforces Round #724 (Div. 2)

A. Omkar and Bad Story

通过样例会发现只要有负数就会无解,因为最大的数一旦拿去减最小的数就会出现更大的数,更大的数又可以跟负数凑出更大的数,无法构造。只有非负数的时候不难想到直接把所有数填入即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define forn(i,x,n) for(int i = x;i <= n;++i)
#define forr(i,x,n) for(int i = n;i >= x;--i)
#define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)

const int N = 105;
int a[N];

int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        int n;scanf("%d",&n);
        forn(i,1,n) scanf("%d",&a[i]);
        bool neg = 0;
        forn(i,1,n) if(a[i] < 0)    neg = 1;
        if(neg) 
        {
            puts("NO");
            continue;
        }
        puts("YES");
        puts("101");
        forn(i,0,100)   printf("%d ",i);
        puts("");
    }

    return 0;
}

B. Prinzessin der Verurteilung

不难猜到按题目要求的MEX的大小不会很大,直接暴力查即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define forn(i,x,n) for(int i = x;i <= n;++i)
#define forr(i,x,n) for(int i = n;i >= x;--i)
#define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)

int n;
string s;

string bfs()
{
    queue<string> q;
    forn(i,0,25)    
    {
        char ch = 'a' + i;
        string _;_.push_back(ch);
        q.push(_);
    }
    while(!q.empty())
    {
        string u = q.front();q.pop();
        if(s.find(u) == string::npos)   return u;
        forn(i,0,25)
        {
            char ch = 'a' + i;
            u.push_back(ch);
            q.push(u);
            u.pop_back();
        }
    }
}

int main()
{
    Angel_Dust;
    int T;cin >> T;
    while(T--)
    {
        cin >> n >> s;
        cout << bfs() << endl;
    }
    return 0;
}

C. Diluc and Kaeya

首先考虑一个dp

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define forn(i,x,n) for(int i = x;i <= n;++i)
#define forr(i,x,n) for(int i = n;i >= x;--i)
#define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
#define x first
#define y second

const int N = 5e5+7;
int sumD[N],sumK[N],f[N];
char s[N];

int gcd(int x,int y)
{
    if(y == 0)  return x;
    return gcd(y,x % y);
}

int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        int n;scanf("%d",&n);
        forn(i,1,n) f[i] = 0;
        scanf("%s",s + 1);
        forn(i,1,n)
        {
            sumD[i] = sumD[i - 1] + (s[i] == 'D');
            sumK[i] = sumK[i - 1] + (s[i] == 'K');
        }

        map<pii,int> st;
        forn(i,1,n)
        {
            pii cur = {sumD[i] / gcd(sumD[i],sumK[i]),sumK[i] / gcd(sumD[i],sumK[i])};
            ++st[cur];
            printf("%d ",st[cur]);
        }
        puts("");
    }
    return 0;
}

D. Omkar and Medians

直接按题目的要求模拟:显然首先有\(a[1] = b[1]\),直接放入就可以了。不难发现后面的过程就是每次插入两个数,使整个数组的中位数使某个要求的值。

对于构造\(b[i]\)成为中位数的过程:首先设还需要插入的数的个数是\(k\),特别地,如果一开始\(b[i]\)并不在当前的\(a\)里面,那么需要首先消耗一次插入机会把\(b[i]\)放进来。其次求出\(>b[i]\)和\(<b[i]\)的数的数量,分别记为\(up,dw\)。由于这样的构造保证每个\(b[i]\)只存在一个,所以可以不用管可能有多个\(b[i]\)的情况。再者,如果\(up == dw\)即\(b[i]\)已经是整个序列的中位数了,那么首位各插入一个正负无穷大,就可以保证中位数还是\(b[i]\)了。反之如果\(|up - dw| \neq k\),说明无解,否则的话按\(up\)与\(dw\)的大小关系插入正负无穷大来使\(b[i]\)移动到中位数的位置即可。

那么为了查询\(b[i]\)与整个数组中其他数的大小关系,写一个维护值域上元素个数的数据结构即可,代码中实现的是离散化后维护BIT。注意本题是多测,每次操作之后需要把BIT清空,需要写一些额外的代码来记录整个BIT的状态完成清空。

但是本题让使用memset清空的代码跑过了,可能是没人hack,原则上应该是会被卡的。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define forn(i,x,n) for(int i = x;i <= n;++i)
#define forr(i,x,n) for(int i = n;i >= x;--i)
#define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)

const int N = 2e5+7;
int c[N],b[N];
vector<int> val;

inline int lowbit(int x)
{
    return x & -x;
}

void modify(int x,int v)
{
    for(int i = x;i < N;i += lowbit(i))
        c[i] += v;
}

int query(int x)
{
    int res = 0;
    for(int i = x;i;i -= lowbit(i))
        res += c[i];
    return res;
}

int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        val.clear();

        int n;scanf("%d",&n);
        forn(i,1,n) scanf("%d",&b[i]),val.push_back(b[i]);
        sort(val.begin(),val.end());val.erase(unique(val.begin(),val.end()),val.end());
        forn(i,1,n) b[i] = lower_bound(val.begin(),val.end(),b[i]) - val.begin() + 2;

        val.clear();

        bool ok = 1;
        int cneginf = 0,cposinf = 0;
        modify(b[1],1);val.push_back(b[1]);
        forn(i,2,n)
        {
            int k = 2;
            if(query(b[i]) - query(b[i] - 1) == 0)  modify(b[i],1),--k,val.push_back(b[i]);
            int dw = query(b[i] - 1),up = query(N - 1) - query(b[i]);
            if(up == dw && k == 2)
            {
                ++cneginf;++cposinf;
                modify(N - 1,1);modify(1,1);
                continue;
            }
            if(abs(up - dw) != k)  
            {
                ok = 0;
                break;
            }
            forn(_,1,k) if(up > dw) modify(1,1),++cneginf;else modify(N - 1,1),++cposinf;
        }
        
        if(ok)  puts("YES");
        else puts("NO");

        for(auto& v : val)  modify(v,-1);
        forn(_,1,cneginf)   modify(1,-1);
        forn(_,1,cposinf)   modify(N - 1,-1);
    }
    return 0;
}

标签:forn,val,int,题解,modify,--,724,Div,define
来源: https://www.cnblogs.com/HotPants/p/14864629.html