Codeforces Round 1040 (Div. 2)(A~D,E1赛后补)

状态不佳,rating--,blog质量--,有点抱歉

A. Submission is All You Need

思路:mex操作优于max操作只限定于{0},{0,1},其他都是sum更优秀.所以直接判断0,1数量即可

吐槽:没判多余的0,wa了发

#include<iostream>
#include<queue>
#include<map>
#include<iomanip>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#include<functional>
#define ll                            long long
#define ull unsigned long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
const ll maxn = 2e5 + 5;
ll ksm(ll x, ll y)
{
    ll ans = 1;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans % mod;
}
void fio()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
int main() {
    fio();
    ll t=1;
    cin>>t;
    while(t--){
        ll n;
        cin>>n;
        vector<ll>a(n+2);
        ll c0=0;
        ll c1=0;
        ll sum=0;
        for(ll i=1;i<=n;i++){
            cin>>a[i];
            c0+=(a[i]==0);
            c1+=(a[i]==1);
            if(a[i]>=2)sum+=a[i];
        }
        sum+=min(c0,c1)*2;
        ll u=min(c0,c1);
        c0-=u;
        c1-=u;
        sum+=c1+c0;
        cout<<sum<<endl;
    }
    return 0;
}

B. Pathless

思路:设sum为数组总和,如果s<sum随便顺序输出,如果s=sum则-1,如果s>sum,且s-sum的差不等于x * 2+y * 3(x>=0&&y>=0),那么直接0021构造即可,否则怎么构造都无解

#include<iostream>
#include<queue>
#include<map>
#include<iomanip>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#include<functional>
#define ll                            long long
#define ull unsigned long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
const ll maxn = 2e5 + 5;
ll ksm(ll x, ll y)
{
    ll ans = 1;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans % mod;
}
void fio()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
int main() {
    fio();
    ll t=1;
    cin>>t;
    while(t--){
        ll n,s;
        cin>>n>>s;
        vector<ll>a(n+2);
        ll sum=0;
        for(ll i=1;i<=n;i++)cin>>a[i],sum+=a[i];
        if(sum==s)cout<<-1<<endl;
        else if(s<sum){
            for(ll i=1;i<=n;i++)cout<<a[i]<<" ";
            cout<<endl;
        }
        else {
            ll dd=s-sum;
            ll c0=0,c2=0;
            for(ll i=1;i<=n;i++){
                c0+=(a[i]==0);
                c2+=(a[i]==2);
                // c3+=(a[i]==3);
            }
            bool flag=0;
            for(ll j=0;j<=1000;j++){
                if(j*2<=dd){
                    if((dd-j*2)%3==0){
                        flag=1;
                        break;
                    }
                }
            }
            if(flag)cout<<-1<<endl;
            else {
                for(ll i=1;i<=n;i++){
                  if(c0>0){
                    c0--;
                    cout<<0<<" ";
                  }  
                  else if(c2>0){
                    c2--;
                    cout<<2<<" ";
                  }
                  else {
                    cout<<1<<" ";
                  }
                }
                cout<<endl;
            }
        }
    }
    return 0;
}

C. Double Perspective

思路:显然如果构成了环,那么其的并集将会重复一次,所以考虑直接连边,然后直接dfs得出答案即可,可能是多个连通分量,每个点都去dfs一下即可(使用vis标记),不走已被vis标记过的点(防止成环)

吐槽:这个n * n<=9e6看得真难受

#include<iostream>
#include<queue>
#include<map>
#include<iomanip>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#include<functional>
#define ll                            long long
#define ull unsigned long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
const ll maxn = 2e5 + 5;
ll ksm(ll x, ll y)
{
    ll ans = 1;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans % mod;
}
void fio()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
int main() {
    fio();
    ll t=1;
    cin>>t;
    while(t--){
        ll n;
        cin>>n;
        vector<vector<pair<ll,ll>>>g(n*2+4);
        for(ll i=1;i<=n;i++){
            ll l,r;
            cin>>l>>r;
            g[l].push_back({r,i<<1});
            g[r].push_back({l,i<<1|1});
            // b[i]={l,r};
        }
        vector<bool>vi(n*2+2,0);
        vector<ll>d;
        function<void(ll)>dfs=[&](ll x){
            vi[x]=1;
            for(auto [to,j]:g[x]){
                if(vi[to])continue;
                else {
                    d.push_back(j/2);
                    dfs(to);
                }
            }
        };
        for(ll i=1;i<=2*n;i++){
            if(vi[i]==0){
                dfs(i);
            }
        }
        cout<<d.size()<<endl;
        sort(d.begin(),d.end());
        for(auto j:d)cout<<j<<" ";
        cout<<endl;
    }
    return 0;
}

D. Stay or Mirror

思路:这道题分类讨论下,讨论x和2 * n-x产生的必定贡献,谁更小选谁,相等选x(不知道选n * 2-x是否一样)。这个思路没有严谨证明,赛时想了下试了下就过了。

#include<iostream>
#include<queue>
#include<map>
#include<iomanip>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#include<functional>
#define ll                            long long
#define ull unsigned long long
#define lowbit(x) (x & -x)
#define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 998244353;
const ll maxn = 2e5 + 5;
ll ksm(ll x, ll y)
{
    ll ans = 1;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans % mod;
}
void fio()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
int main() {
    fio();
    ll t = 1;
    cin >> t;
    while (t--) {
        ll n;
        cin >> n;
        vector<ll>a(n + 2);
        for (ll i = 1; i <= n; i++)cin >> a[i];
        vector<ll>vis(n * 2 + 5, 0);
        for (ll i = 1; i <= n; i++) {
            ll l = min(a[i], 2 * n - a[i]);
            ll r = max(a[i], 2 * n - a[i]);
            ll c1 = 0, c2 = 0;
            vector<ll>now(n * 2 + 5, 0);
            for (ll j = r - 1; j >= 1; j--) {
                if (vis[j] == 0 && now[j] == 0 && 2 * n - j <= r - 1) {
                    now[j] = now[2 * n - j] = 1;
                    c1++;
                }
            }
            ll c3 = 0;
            for (ll j = r + 1; j <= 2*n; j++) {
                if (vis[j] == 1)c3++;
            }
            for (ll j = l + 1; j <= 2 * n; j++) {
                if (vis[j] == 1)c2++;
            }
            if (c2 <= c3 + c1) {
                a[i] = l;
                vis[r] = -1, vis[l] = 1;
            }
            else a[i] = r, vis[l] = -1, vis[r] = 1;
        }
        ll ans = 0;
        vector<bool>vi(n * 2 + 2, 0);
        for (ll i = 1; i <= n; i++) {
            for (ll j = a[i] + 1; j <= 2 * n; j++)ans += (vi[j] == 1);
            vi[a[i]] = 1;
        }
        cout << ans << endl;
    }
    return 0;
}

E1. Interactive RBS (Easy Version)

思路:询问次数很多,先考虑二分出左括号位置和右括号位置(a1,a2),那么构造如下格式((()()a[i-1]a[i]即可根据值知道答案,最大询问次数为500+log2(1000) * 2。

#include<iostream>
#include<queue>
#include<map>
#include<iomanip>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#include<functional>
#define ll                            long long
#define ull unsigned long long
#define lowbit(x) (x & -x)
// #define endl "\n"//                           交互题记得删除
using namespace std;
mt19937 rnd(time(0));
const ll mod = 1e9 + 7;
const ll maxn = 2e5 + 5;
ll ksm(ll x, ll y)
{
    ll ans = 1;
    while (y)
    {
        if (y & 1)
        {
            ans = ans * x % mod;
        }
        x = x * x % mod;
        y >>= 1;
    }
    return ans % mod;
}
void fio()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}
int main() {
    fio();
    ll t = 1;
    cin >> t;
    while (t--) {
        ll  n;
        cin >> n;
        ll a1, a2;
        ll l = 2, r = n;
        function<ll(ll)>q1 = [&](ll x) {
            cout << "? " << x;
            for (ll i = 1; i <= x; i++)cout << " " << i;
            cout << endl;
            cout.flush();
            cin >> x;
            return x;
            };
        function<ll(ll)>q2 = [&](ll x) {
            cout << "? " << n - x+1;
            for (ll i = x; i <= n; i++)cout << " " << i;
            cout << endl;
            cout.flush();
            cin >> x;
            return x;
            };
        while (l < r) {
            ll mid = l + r >> 1;
            if (q1(mid))r = mid;
            else l = mid + 1;
        }
        if (q1(r))a1 = r;
        else a1 = 1;
        l = 1, r = n - 1;
        while (l <= r) {
            ll mid = l + r >> 1;
            if (q2(mid))l = mid + 1;
            else r = mid - 1;
        }
        if (r == 0)r = 1;
        if (q2(r))a2 = r;
        else a2 = n;
        swap(a1, a2);
        vector<char>a(n + 2);
        for (ll i = 2; i <= n; i += 2) {
            cout << "? " << 8 << " " << a1 << " " << a1 << " " <<a1<<" "<<a2 << " " << a1 << " " << a2 << " " << i - 1 << " " << i << endl;
            cout.flush();
            ll x;
            cin >> x;
            if (x == 6)a[i - 1] = '(', a[i] = ')';
            else if (x == 4)a[i - 1] = ')', a[i] = '(';
            else if (x == 3)a[i - 1] = '(', a[i] = '(';
            else a[i - 1] = ')', a[i] = ')';
        }
        if (n & 1) {
            cout << "? " << 2 << " " << n << " " << a2 << endl;
            cout.flush();
            ll x;
            cin >> x;
            if (x > 0)a[n] = '(';
            else a[n] = ')';
        }
        cout << "! ";
        for (ll i = 1; i <= n; i++)cout << a[i];
        cout << endl;
        //((()()() 6
        //((()())( 4
        //((()()(( 3
        //((()())) 5 
    }
    return 0;
}

posted @ 2025-08-01 02:31  长皆  阅读(83)  评论(0)    收藏  举报