Codeforces Round #829#830

Posted 钟钟终

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #829#830相关的知识,希望对你有一定的参考价值。

D1. Balance (Easy version)

思路:刚开始使用set查找元素超时了。之后想到我只要判断出元素在不在几何中就好,由于数组需要离散化,所以开map记录。
mp:记录元素是否出现在集合中;
a:记录该元素对应的最小倍数,及时用while暴力更新

#include<bits/stdc++.h>
#define int long long
#define endl '\\n'
#define For(i,a,b) for(i=(a);i<=(b);++i)
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
using namespace std;
const int N=2e5+5;
const int inf=1e18;
const int mod=998244353;
char c;int x;
map<int,int>mp,a;
void solve()

    mp[0]=1;
    int q;cin>>q;
    while(q--)
    
        cin>>c>>x;
        if(c=='+')
            mp[x]=1;
        else
        
            int tmp=a[x];
            while(mp[tmp]) tmp+=x;
            a[x]=tmp;
            cout<<tmp<<endl;
        
    

signed main()

    ios;
    //int T;cin>>T;
    //while(T--)
        solve();
    return 0;


//int fac[N],inv[N];
//int qpow(int a,int b)
//    int res=1;
//    while(b)
//    
//        if(b&1) res=res*a%mod;
//        a=a*a%mod;
//        b>>=1;
//    
//    return res;
//
//int getinv(int x)return qpow(x,mod-2);
//int C(int a,int b)
//
//    return (fac[a]*inv[a-b]%mod)*inv[b]%mod;
//

C1. Make Nonzero Sum (easy version)

这题做的时候是真的么思路,觉得情况很复杂,区间的大小不好控制,正负1的也会随着位置而改变作用。知道后来,队友的出现……把我讲懂了。当时讲到每个数作为一个区间的情况,怎么就不往下再想想……
思路:
1.通常情况下,正负1的个数相等,每个数作为一个区间,肯定可以约掉。若正负1的数量加起来是个奇数,此情况无解。
2.此外若出现连续个1,则第二个1、第四个1……可转化为-1看待,两两为一组区间,直到正1和负1的数量相等。
3.若出现连续个-1,情况与2类似。

#include<bits/stdc++.h>
#define int long long
#define endl '\\n'
#define For(i,a,b) for(i=(a);i<=(b);++i)
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
using namespace std;
const int N=2e5+5;
const int inf=1e18;
const int mod=998244353;
int n,a[N];
bool vis[N];
vector<pair<int,int>>e;
void solve()

    e.clear();
    cin>>n;
    for(int i=0;i<=n+5;i++) vis[i]=0;
    int num1=0,num2=0;
    for(int i=1;i<=n;i++)
    
        cin>>a[i];
        if(a[i]==1) num1++;
        else if(a[i]==-1) num2++;
    
    if((num1+num2)%2!=0)
    
        cout<<-1<<endl;return;
    
    if(num1==num2)
    
        for(int i=1;i<=n;i++) e.push_back(i,i);
    
    else if(num1>num2)
    
        for(int i=1;i<n&&num1>num2;i++)
        
            if(a[i]==1&&a[i+1]==1)
            
                e.push_back(i,i+1);num1--;num2++;
                vis[i]=vis[i+1]=1;
                i++;
            
        
        for(int i=1;i<=n;i++)
        if(!vis[i]) e.push_back(i,i);
    
    else
    
        for(int i=1;i<n&&num1<num2;i++)
        
            if(a[i]==-1&&a[i+1]==-1)
            
                e.push_back(i,i+1);num2--;num1++;
                vis[i]=vis[i+1]=1;
                i++;
            
        
        for(int i=1;i<=n;i++)
        if(!vis[i]) e.push_back(i,i);
    
    cout<<e.size()<<endl;
    sort(e.begin(),e.end(),[&](pair<int,int> &p,pair<int,int> &q)
         return p.first<q.first;
    );
    for(auto x:e)
    
        cout<<x.first<<" "<<x.second<<endl;
    

signed main()

    //ios;
    int T;cin>>T;
    while(T--)
        solve();
    return 0;


C2. Make Nonzero Sum (hard version)

思路:
1.在C1的基础上,引入了0,可分析出,在大方向正1和负1相等时,又多出两种情况。
2.0后面跟着1,可看作为-1。0后面跟着-1,可看作1.

#include<bits/stdc++.h>
#define int long long
#define endl '\\n'
#define For(i,a,b) for(i=(a);i<=(b);++i)
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
using namespace std;
const int N=2e5+5;
const int inf=1e18;
const int mod=998244353;
int n,a[N];
bool vis[N];
vector<pair<int,int>>e;
void solve()

    e.clear();
    cin>>n;
    for(int i=0;i<=n+5;i++) vis[i]=0;
    int num1=0,num2=0;
    for(int i=1;i<=n;i++)
    
        cin>>a[i];
        if(a[i]==1) num1++;
        else if(a[i]==-1) num2++;
    
    if((num1+num2)%2!=0)
    
        cout<<-1<<endl;return;
    
    if(num1==num2)
    
        for(int i=1;i<=n;i++) e.push_back(i,i);
    
    else if(num1>num2)
    
        for(int i=1;i<n&&num1>num2;i++)
        
            if((a[i]==1&&a[i+1]==1)||(a[i]==0&&a[i+1]==1))
            
                e.push_back(i,i+1);num1--;num2++;
                vis[i]=vis[i+1]=1;
                i++;
            
        
        for(int i=1;i<=n;i++)
        if(!vis[i]) e.push_back(i,i);
    
    else
    
        for(int i=1;i<n&&num1<num2;i++)
        
            if((a[i]==-1&&a[i+1]==-1)||(a[i]==0&&a[i+1]==-1))
            
                e.push_back(i,i+1);num2--;num1++;
                vis[i]=vis[i+1]=1;
                i++;
            
        
        for(int i=1;i<=n;i++)
        if(!vis[i]) e.push_back(i,i);
    
    cout<<e.size()<<endl;
    sort(e.begin(),e.end(),[&](pair<int,int> &p,pair<int,int> &q)
         return p.first<q.first;
    );
    for(auto x:e)
    
        cout<<x.first<<" "<<x.second<<endl;
    

signed main()

    //ios;
    int T;cin>>T;
    while(T--)
        solve();
    return 0;


C1. Sheikh (Easy version)

分析:这题写代码写的很差,出现了好几个小错误,都没看出来。
1.关键点:从1开始,每多出一个数值,f的值肯定是递增的,因此最大值肯定为f[n]时。
2.存在不从1开始的起点,长度为len,其值也为f[n]。

#include<bits/stdc++.h>
#define int long long
#define endl '\\n'
#define For(i,a,b) for(i=(a);i<=(b);++i)
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
using namespace std;
const int N=2e5+5;
const int inf=1e18;
const int mod=998244353;
int n,q,a[N],mx,ll,rr;
int sum[N],xr[N];
bool check(int x)

    int res=0;
    for(int i=x;i<=n;i++)
    
        int tmp=sum[i]-sum[i-x]-(xr[i]^xr[i-x]);
        if(res<=tmp)
        
            res=tmp;ll=i-x+1,rr=i;
        
    
    if(res>=mx)
    
        return 1;
    
    else return 0;

void solve()

    cin>>n>>q;
    for(int i=0;i<=n+5;i++) sum[i]=a[i]=xr[i]=0;
    ll=rr=mx=0;
    for(int i=1;i<=n;i++)
    
        cin>>a[i];
        sum[i]=sum[i-1]+a[i];
        xr[i]=xr[i-1]^a[i];
    
    int p,q;cin>>p>>q;
    mx=sum[n]-xr[n];
//    for(int i=1;i<=n;i++)
//    
//        cout<<sum[i]<<" "<<xor[i]<<" "<<f[i]<<endl;
//    
    int l=1,r=n,mid,ans;
    while(l<=r)
    
        mid=(l+r)>>1;
        if(check(mid))
            r=mid-1,ans=mid;
        else
            l=mid+1;
    
    check(ans);
    cout<<ll<<" "<<rr<<endl;

signed main()

    ios;
    int T;cin>>T;
    while(T--)
        solve();
    return 0;以上是关于Codeforces Round #829#830的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #829 Div. 2 D. Factorial Divisibility(结论&数学)

CodeForces 830A Office Keys

Codeforces 830D Singer House - 动态规划

截断字符串的中间并替换它 - Swift

[set]Codeforces 830B-Cards Sorting

Codeforces 830D Singer House 动态规划