IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> Codeforces Round #772 (Div. 2) A B C D -> 正文阅读

[C++知识库]Codeforces Round #772 (Div. 2) A B C D

Codeforces Round #772 (Div. 2) A B C D

A. Min Or Sum

思路: 一眼题,最好的情况就是二进制形式下出现过的数字最多保留 1 1 1位。全部 ∣ | 起来即可。

  • 参考代码:
#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define int long long 
#define re register int
#define pb emplace_back
#define lowbit(x) (x&-x)
#define fer(i,a,b) for(re i = a ; i <= b ; i ++)
#define der(i,a,b) for(re i = a ; i >= b ; i --)
#define snow ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int lcm(int a,int b){return a*b/gcd(a,b);}
typedef pair<int,int>PII;
typedef pair<int,string>PIS;
signed main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int k=0;
        for(int i=1;i<=n;i++){
            int x;
            cin>>x;
            k|=x;
        }
        cout<<k<<endl;
    }
    return 0;
}

B. MEX and Array

思路: 贪心,从左到右扫描,如果碰到 L o c a l Local Local M a x i m u m s Maximums Maximums,那么改变右边的数使 a [ i + 1 ] a[i+1] a[i+1]变成 m a x ( a [ i ] , a [ i + 2 ] ) max(a[i],a[i+2]) max(a[i],a[i+2])。为什么取 m a x max max呢,因为如果 a [ i + 2 ] a[i+2] a[i+2] a [ i ] a[i] a[i]大,那么我们显然将 a [ i + 1 ] a[i+1] a[i+1]变成a[i+2]更好,因为不但满足使得左边的 L o c a l Local Local M a x i m u m s Maximums Maximums消失,并且确保右边的 a [ i + 2 ] a[i+2] a[i+2]一定无法构成 L o c a l Local Local M a x i m u m s Maximums Maximums,即是 a [ i + 3 ] a[i+3] a[i+3] a [ i + 2 ] a[i+2] a[i+2]小。反之如果 a [ i + 1 ] a[i+1] a[i+1]变成 a [ i ] a[i] a[i]那么左边确实保证了 L o c a l Local Local M a x i m u m s Maximums Maximums消失,但是如果 a [ i + 3 ] a[i+3] a[i+3] a [ i + 2 ] a[i+2] a[i+2]小,我们又要浪费一次机会去放大 a [ i + 3 ] a[i+3] a[i+3],显然前者更优。

  • 参考代码:
#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define int long long 
#define re register int
#define pb emplace_back
#define lowbit(x) (x&-x)
#define fer(i,a,b) for(re i = a ; i <= b ; i ++)
#define der(i,a,b) for(re i = a ; i >= b ; i --)
#define snow ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int lcm(int a,int b){return a*b/gcd(a,b);}
typedef pair<int,int>PII;
typedef pair<int,string>PIS;
const int N=2e5+10;
int a[N];
signed main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        int ans=0;
        for(int i=2;i<=n-1;i++){
            if(a[i]>a[i-1]&&a[i]>a[i+1]){
                a[i+1]=max(a[i],a[i+2]);
                ans++;
            }
        }
        cout<<ans<<endl;
        for(int i=1;i<=n;i++)cout<<a[i]<<' ';
        cout<<endl;
    }
    return 0;
}

C. Differential Sorting

思路: 比赛时候 C C C翻水水了,歪掉了。以为区间维护,一开始写了 3 3 3 s t r u c t struct struct维护后缀区间最值。后来 w a wa wa掉了。 正解:从性质出发:1.如果 a [ n ? 1 ] > a [ n ] a[n-1]>a[n] a[n?1]>a[n]必错,因为 a [ n ? 1 ] a[n-1] a[n?1]无法成为一个小于等于 a [ n ] a[n] a[n]的数。2:如果 a [ n ] a[n] a[n]是正数,那么在满足性质 1 1 1情况下必然可以通过 n ? 2 n-2 n?2次构造使得前 n ? 2 n-2 n?2个数全部变成 a [ n ? 1 ] ? a [ n ] a[n-1]-a[n] a[n?1]?a[n]。3:如果 a [ n ] a[n] a[n]是负数,前面出现的数必然都是负数才行,一旦出现 a [ i ] > a [ i + 1 ] a[i]>a[i+1] a[i]>a[i+1]的情况,那么必然无法使得 a [ i ] < = a [ i + 1 ] a[i]<=a[i+1] a[i]<=a[i+1],因为小的负数-大的负数为大于等于 0 0 0的整数,也必然 > a [ i + 1 ] >a[i+1] >a[i+1],所以一旦有 a [ n ] a[n] a[n]是负数,除非原数组本身是非降序,操作次数为 0 0 0,否则一定是 ? 1 -1 ?1

  • 参考代码:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int a[N];
int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)cin>>a[i];
        int x=a[n-1]-a[n];
        if(x>0){
            cout<<"-1"<<endl;
            continue;
        }
        if(a[n]<0){
            bool ok=true;
            for(int i=1;i<=n-1;i++){
                if(a[i]>a[i+1])ok=false;
            }
            if(ok){
                cout<<0<<endl;
                continue;
            }
            cout<<"-1"<<endl;
        }
        else{
            cout<<n-2<<endl;
            for(int i=1;i<=n-2;i++){
                cout<<i<<' '<<n-1<<' '<<n<<endl;
            }
        }
    }
    return 0;
}

D. Infinite Set

思路: 通过题目可知除了本身在 a a a数组中出现过的数在 S S S中,依次迭代的 2 ? a [ i ] + 1 2*a[i]+1 2?a[i]+1 4 ? a [ i ] 4*a[i] 4?a[i]也会依次出现在容器中。那么必定有 k < = f ( x ) < k + 1 k<=f(x)<k+1 k<=f(x)<k+1 k k k k + 1 k+1 k+1 n n n在__ l o g ( ) log() log()下的左右边界。例如 2 2 < = f ( 5 ) < 2 3 2^2<=f(5)<2^3 22<=f(5)<23,那么 k 为 2 k为2 k2 k + 1 k+1 k+1 3 3 3,那么显然 f ( x ? 2 + 1 ) f(x*2+1) f(x?2+1)的左边界为 k + 1 k+1 k+1 f ( x ? 4 ) f(x*4) f(x?4)的左边界为 k + 2 k+2 k+2。那么我们很容易发现一个 d p dp dp转移方程,左边界为 k + 2 k+2 k+2的方案数除了本身以外还可以从 k k k k + 1 k+1 k+1处转移过来,分别通过方程 f ( x ? 4 ) f(x*4) f(x?4) f ( x ? 2 + 1 ) f(x*2+1) f(x?2+1)。并且在方程转移开始之前我们需要删掉无用的在 a a a数组中重复出现的数,避免一个相同的数被多次重复计算。例如 a [ 1 ] = 5 , a [ 2 ] = 10 a[1]=5,a[2]=10 a[1]=5a[2]=10 a [ 2 ] a[2] a[2]可以通过 a [ 1 ] a[1] a[1]获得,所以 a [ 2 ] a[2] a[2]我们没必要继续保留。那么这个操作的实现只需将数组从小到大排序,如果将一个数回溯的过程遇到了之前标记过的数说明这个数可以通过前面标记过的数获得而来,那么没必要继续保存。例如: 35 35 35回溯过程是 35 35 35 17 17 17 8 8 8 2 2 2。如果前面这个数出现任意,那么 35 35 35即可被转移过来。那么接下去我们就可以进行 d p dp dp转移,统计最终的总数小于 2 p 2^p 2p的个数。还有一点,为什么进行 d p dp dp转移过程中不会出现同样的数呢?因为我们前面已经将所有会被任意小数转移过来的大数全部删除,那么剩余留在数组中的数必然全是互相不可转移。并且转移路线唯一,什么意思呢?比如上面提到的 35 35 35,回溯路径是唯一的,假使后期转移过程出现相同的数,那么说明这个数不断回溯到原数组中会出现 a [ j ] a[j] a[j]可以被 a [ i ] a[i] a[i]转移而来的情况,那么显然与我们已经删掉所有干扰数相矛盾。所以转移方案数中的数都是独一无二的

  • 参考代码:
#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
#define int long long 
#define re register int
#define pb emplace_back
#define lowbit(x) (x&-x)
#define fer(i,a,b) for(re i = a ; i <= b ; i ++)
#define der(i,a,b) for(re i = a ; i >= b ; i --)
#define snow ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int lcm(int a,int b){return a*b/gcd(a,b);}
typedef pair<int,int>PII;
typedef pair<int,string>PIS;
const int N=2e5+10;
int a[N];
const int mod=1e9+7;
signed main(){
    int n,p;
    cin>>n>>p;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    unordered_map<int,int>hash;
    sort(a+1,a+1+n);
    vector<int>S;
    for(int i=1;i<=n;i++){
        int j=a[i];
        bool ok=true;
        while(j){
            if(hash[j]==1)ok=false;
            if(j&1)j>>=1;
            else if(j&3)break;
            else j>>=2;
        }
        if(ok){//如果无法转移过来那么放进S中
            hash[a[i]]=1;
            S.push_back(a[i]);
        }
    }
    vector<int>sum(30),dp(p);
    for(auto x:S){
        sum[__lg(x)]++;
    }
    int ans=0;
    for(int i=0;i<p;i++){
        if(i<30){
            dp[i]=sum[i];
        }
        if(i>=1){
            dp[i]=(dp[i]+dp[i-1])%mod;
        }
        if(i>=2){
            dp[i]=(dp[i]+dp[i-2])%mod;
        }
        ans=(ans+dp[i])%mod;
    }
    cout<<ans<<endl;
    return 0;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-22 20:23:18  更:2022-02-22 20:23:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:34:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码