Codeforces Round #752 (Div. 2) (A to D)

Codeforces Round #752 (Div. 2)

A

题目:

向一个序列中任意位置插入元素,求把一个序列变成满足对任意的元素有, a i < = i a_i<=i ai<=i,的最小操作次数。

思路

  • 显然往头部插入,对答案有最大的贡献,只要对所有元素操作次数取max即可

###AC代码

#include <bits/stdc++.h>
#define yes puts("yes");
#define inf 0x3f3f3f3f
#define ll long long
#define linf 0x3f3f3f3f3f3f3f3f
#define debug(x) cout<<"> "<< x<<endl;
#define ull unsigned long long
#define endl '\n'
#define lowbit(x) x&-x
//#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N =10 + 1e5 ,mod=1e9 + 7;
int n;
int a[N];
void solve()
{    
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    int ans =0 ;
    for(int i=1;i<=n;i++){
        if(i+ans<a[i]){
            ans += a[i] - (i+ans);
        }
    }
    cout << ans << endl;
}
signed main()
{
    ios::sync_with_stdio();cin.tie();cout.tie();

    int T;cin>>T;
    while(T--)
        solve();

    return 0;
}

B

题目:

可以把一个序列分成若干个连续的部分,对每个子数组的最长上升子序列的长度求异或和,问最后能否有一种方案使得这个异或和为0.

思路

  • 乍一看很难,但仔细思考其实就是一个简单的构造,对于异或和的问题,要求为0,优先考虑奇偶性,以及寻找相同的元素。
  • 显然,如果n为偶数,那么,把这个序列分为n份,每份的最长上升子序列都是1,偶数个1的异或一定是0.
  • 对于n为奇数的情况,考虑化归为偶数,因为对于一个非严格递减的序列,它的贡献恒为1,所以如果找到一个长度为偶数的非严格递减序列,它可以等价为一个元素,这样就变成了奇数个1和这个等价元素提供的1,它们的异或和为0。如此确切的讲,只要找到一个长度为2的非严格递减片段,那么这个序列的构造方案就是存在的。

AC代码

#include <bits/stdc++.h>
#define yes puts("yes");
#define inf 0x3f3f3f3f
#define ll long long
#define linf 0x3f3f3f3f3f3f3f3f
#define debug(x) cout<<"> "<< x<<endl;
#define ull unsigned long long
#define endl '\n'
#define lowbit(x) x&-x
//#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N =10 + 1e5 ,mod=1e9 + 7;
int n;
int a[N];
void solve()
{    
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    if(n%2==0){
        cout <<"YES\n";
        return;
    }
    for(int i=2;i<=n;i++){
        if(a[i]<=a[i-1]){
            cout<<"YES\n";
            return;
        }
    }
    cout<<"NO\n";
}
signed main()
{
    ios::sync_with_stdio();cin.tie();cout.tie();

    int T;cin>>T;
    while(T--)
        solve();

    return 0;
}

C

题目:

对一个序列某个元素,如果它无法被 i + 1 i+1 i+1,整除,那么我们就可以删除这个元素,问最后是否可以把这个序列给删成空序列。

思路

  • 容易观察到,对第一个元素,它只可能和2做除法。假设第一个元素是可以删除的,考虑第二个元素,首先它可以和3做除法,又因为1可删,可以通过删除顺序的变更使得第二个元素化归的第一个元素,所以总的来说第二个元素可以和2,3做除法。
  • 以此类推,对第i个元素,它可以和 [ 2 , i + 1 ] [2,i+1] [2,i+1]的元素做除法,只要存在一个元素使得这个元素除不尽,这就是可删的。
  • 另外,如果一个元素无法被删除,也即它是 [ 2 , i + 1 ] [2,i+1] [2,i+1]这个区间中所有数字的公倍数,当 i > 22 i>22 i>22后,LCM也超过了1e9了,在1e9范围内的整数如果无法被删除,它的i一定不会超过22,如果一个元素可以被删除, [ 1 , 22 ] [1,22] [1,22]中一定有一个数字使得除不尽,所以即使暴力找,他的复杂度也是 O ( n ) O(n) O(n)的.

AC代码

#include <bits/stdc++.h>
#define yes puts("yes");
#define inf 0x3f3f3f3f
#define ll long long
#define linf 0x3f3f3f3f3f3f3f3f
#define debug(x) cout<<"> "<< x<<endl;
#define ull unsigned long long
#define endl '\n'
#define lowbit(x) x&-x
//#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N =10 + 1e5 ,mod=1e9 + 7;
int n;
int a[N];
void solve()
{    
    p.clear();
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++){
        bool ok = 0;
        for(int j=2;j<=i+1;j++)
            if(a[i]%j){
                ok = 1;
                break;
            }
        if(!ok){
            cout<<"NO\n";
            return;
        }
    }
    cout << "YES\n";
}
signed main()
{
    ios::sync_with_stdio();cin.tie();cout.tie();

    int T;cin>>T;
    while(T--)
        solve();

    return 0;
}

D

题目:

求一个n,满足 n m o d x = y m o d n n mod x=y mod n nmodx=ymodn.

思路

  • 显然对于 x = y x=y x=y x > y x>y x>y的情况很好解决
  • 如果 x < y x<y x<y,打表可知n在 [ x , y ] [x,y] [x,y]中,可以构造出:n是一个比kx多t的数,并且n比y少t,可得构造公式.

PS:不好描述,详见官方题解.

AC代码

#include <bits/stdc++.h>
#define yes puts("yes");
#define inf 0x3f3f3f3f
#define ll long long
#define linf 0x3f3f3f3f3f3f3f3f
#define debug(x) cout<<"> "<< x<<endl;
#define ull unsigned long long
#define endl '\n'
#define lowbit(x) x&-x
//#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N =10 + 1e5 ,mod=1e9 + 7;
int x,y;
ll n;
void solve()
{    
    cin>>x>>y;
    if(x==y){
        cout<<x<<endl;
        return;
    }
    if(x>y){
        cout << x + y<<endl;
        return;
    }else{
        int i = x, j = y;
        //  
        cout << (j / i * i + j) / 2 << endl;
        // cout<<x+1<<endl;
    }
}  
signed main()
{
    ios::sync_with_stdio();cin.tie();cout.tie();

    int T;cin>>T;
    while(T--)
        solve();

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值