首页 > 其他分享 >CF1198题解

CF1198题解

时间:2023-12-01 09:02:21浏览次数:41  
标签:ch int 题解 read while CF1198 getchar

CF1198

Codeforces Round 576 (Div. 1)

CF1198A

link

CF1198A题意

有一种数字化一段录音的常用方式,是记录每一个时刻的强度值。这些非负的强度值就可以代表一段音频

对于一段音频,若有 \(K\) 个不同的强度值,那么每一位我们都需要 \(k = \lceil\log_2K \rceil\) \(\text{bit}\) 来存储

也就是说,为了存储这一段音频,我们需要 \(nk\) 个 \(\text{bit}\)

为了压缩音频大小,我们们采取如下的方式:

选择两个整数 \(l, r(l \leq r)\),对于音频的强度值序列 \(v\),将其作一次变换:

\[v_i = \begin{cases} v_i&l \leq v_i \leq r \\ l &v_i < l\\ r &r < v_i \end{cases} \]

其中第 \(2, 3\) 种情况被视作 \(v_i\) 这个强度值被更改了

你的任务是对于给定的强度值序列 \(a\),找到一组 \(l, r\),使得在经过上述压缩后能够被大小为 \(I \ \text{bytes} (\text{1bytes = 8 bit})\) 的存储器装下,并最小化被更改的强度值的数量。

CF1198A题解

坏了坏了,Eric被1600爆杀了(
首先别读错题,\([l,r]\) 表示值域范围,不是下标范围。
然后计算最多保留的不同数字 \(k = 2^{\lfloor\frac{I}{n}\rfloor}\)。
直接暴力枚举左端点 \(l=i\),则 \(r=i+k-1\),预处理下在这个范围之外的数字有多少个即可。
时间复杂度 \(O(n)\)

CF1198A代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
    int x = 0, f = 1;char ch = getchar();
    while(ch < '0' || ch > '9'){if(ch == '-') f = -1;ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + (ch ^ 48);ch = getchar();}
    return x * f;
}
const int maxn = 4e5 + 10;
int n, I;
int a[maxn], b[maxn];
int pre[maxn], suf[maxn];
int buc[maxn];
int qpow(int x,int a){
    int res = 1;
    while(a){
        if(a & 1)res = res * x;
        if(res >= n)return n;
        x = x  * x;a >>= 1;
        if(x >= n)x = n;
    }
    return res;
}
signed main(){
    n = read(); I = read() * 8;
    for(int i = 1;i <= n;i++){b[i] = a[i] = read();}
    sort(b + 1,b + 1 + n);
    int tot = unique(b + 1,b + 1 + n) - b - 1;
    for(int i = 1;i <= n;i++){a[i] = lower_bound(b + 1,b + 1 + tot,a[i]) - b;}
    for(int i = 1;i <= n;i++)buc[a[i]]++;
    for(int i = 1;i <= tot;i++)pre[i] = buc[i] + pre[i - 1];
    for(int i = tot;i;i--)suf[i] = buc[i] + suf[i + 1];
    int ans = n, k = qpow(2,I / n);
    if(k >= tot){puts("0");return 0;}
    for(int i = 1;i + k - 1 <= tot;i++) ans = min(ans,pre[i - 1] + suf[i + k]);
    printf("%lld\n",ans);

    // printf("tot = %lld, k = %lld\n",tot, k);
    return 0;
}

CF1198B

link

CF1198B题意

给出一个长度为 \(n\) 的数组 \(a\),对它进行 \(m\) 次操作,每个操作如下:

  • \(1\space u\space v\):将 \(a_u\gets v\)。
  • \(2\space u\):将所有小于 \(u\) 的数改成 \(u\)。

问最后的数组。

CF1198B题解

操作 \(1\) 相当于单点修改,操作 \(2\) 相当于区间取 \(max\),这东西线段树随便维护一下就OK了。

CF1198B代码

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    int x = 0, f = 1;char ch = getchar();
    while(ch < '0' || ch > '9'){if(ch == '-') f = -1;ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + (ch ^ 48);ch = getchar();}
    return x * f;
}
const int maxn = 2e5 + 10;
int n, a[maxn], m;
struct Segment_Tree{
    struct node{
        int maxx, tag;
        node(int maxx = 0,int tag = 0):maxx(maxx),tag(tag){}
    }d[maxn << 2];
    node mergenode(node l,node r){return node(max(l.maxx,r.maxx));}
    void pushdown(int p){
        if(d[p].tag){
            d[p << 1].maxx = max(d[p].tag,d[p << 1].maxx);
            d[p << 1].tag = max(d[p].tag,d[p << 1].tag);
            d[p << 1 | 1].maxx = max(d[p].tag,d[p << 1 | 1].maxx);
            d[p << 1 | 1].tag = max(d[p].tag,d[p << 1 | 1].tag);
            d[p].tag = 0;
        }
    }
    void build(int l,int r,int p){
        if(l == r){d[p] = node(a[l]);return;}
        int mid = l + r >> 1;
        build(l,mid,p << 1);build(mid + 1,r,p << 1 | 1);
        d[p] = mergenode(d[p << 1],d[p << 1 | 1]);
    }
    void update(int l,int r,int pos,int p,int upd){
        if(l == r && l == pos){d[p] = node(upd);return;}
        int mid = l + r >> 1;pushdown(p);
        if(pos <= mid)update(l,mid,pos,p << 1,upd);
        else update(mid + 1,r,pos,p << 1 | 1,upd);
        d[p] = mergenode(d[p << 1],d[p << 1 | 1]);
    }
    void update(int l,int r,int s,int t,int p,int upd){
        if(s <= l && r <= t){d[p].tag = max(d[p].tag,upd);d[p].maxx = max(d[p].maxx,upd);return;}
        int mid = l + r >> 1;pushdown(p);
        if(s <= mid)update(l,mid,s,t,p << 1, upd);
        if(mid < t)update(mid + 1,r,s,t,p << 1 | 1,upd);
        d[p] = mergenode(d[p << 1],d[p << 1 | 1]);
    }
    void query(int l,int r,int p){
        if(l == r){printf("%d ",d[p].maxx);return;}
        int mid = l + r >> 1;pushdown(p);
        query(l,mid,p << 1);query(mid + 1,r,p << 1 | 1);
    }
}tree;

signed main(){
    n = read();for(int i = 1;i <= n;i++)a[i] = read();
    tree.build(1,n,1);m = read();int u, opt;
    for(int i = 1;i <= m;i++){
        opt = read(); u = read();
        if(opt == 1)tree.update(1,n,u,1,read());
        else tree.update(1,n,1,n,1,u);
    }
    tree.query(1,n,1);
    return 0;
}

CF1198C

link

CF1198C题意

给一个无向图,\(3\times n\) 个点, \(m\) 条边,请找大小为 \(n\) 的点独立集或边独立集,如果都没有报告无解。

CF1198C题解

首先不存在无解情况,理由很简单,每次加入边的时候,类似最小生成树的形式选择加入哪条边。
然后如果还剩下 \(k\ge n\) 个点没有被任何加入边覆盖,那就一定有点独立集,直接输出即可。
否则表明至少有 \(k\ge 2\times n+1\) 个点是联通的,这些点至少组成 \(n\) 条边,直接输出即可。
故不存在无解的情况,解法也在上文说完了。

CF1198C代码

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    int x = 0, f= 1;char ch = getchar();
    while(ch < '0' || ch > '9'){if(ch == '-') f = -1;ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + (ch ^ 48);ch = getchar();}
    return x * f;
}
const int maxn = 1e5 + 10;
int n, m;
int book[maxn * 3], ans[maxn];
signed main(){
int T = read();
while(T--){
    n = read() * 3;m = read();int cnt = 0;
    for(int i = 1;i <= n;i++)book[i] = 0;
    for(int i = 1;i <= m;i++){
        int u = read(), v = read();
        if(!book[u] && !book[v] && cnt < n / 3){book[u] = book[v] = 1;ans[++cnt] = i;}
    }
    if(cnt >= n / 3){
        puts("Matching");
        for(int i = 1;i <= n / 3;i++){printf("%d ",ans[i]);}
        puts("");
    }
    else{
        puts("IndSet");cnt = 0;
        for(int i = 1;i <= n && cnt < n / 3;i++){
            if(!book[i]){cnt++;printf("%d ",i);}
        }
        puts("");
    }
}
    return 0;
}

标签:ch,int,题解,read,while,CF1198,getchar
From: https://www.cnblogs.com/Call-me-Eric/p/17868838.html

相关文章

  • [AGC052B] Tree Edges XOR 题解
    题目链接点击打开链接题目解法怎么感觉这场\(B\)比\(C\)思维量更大考虑一步很妙的操作:把边权变成点权,以达到简化操作的目的使每条边的边权为两端点的异或和,手画一下可以发现,操作简化成了交换两端点的点权我们定义\(d_{1/2,i}\)定义为在\(1/2\)树上,\(i\)到根的权值......
  • CF1684题解
    CF1684CodeforcesRound792(Div.1+Div.2)CF1684AlinkCF1684A题意有一个用十进制表示的没有前导零的正整数\(n\)。Alice和Bob正在用这个数玩一个游戏。Alice先手,他们轮流进行游戏。在她的这一轮中,Alice应该交换这个数中的任何不同位置的两位。轮到Bob时,他每次......
  • [AGC052C] Nondivisible Prefix Sums 题解
    题目链接点击打开链接题目解法好题!一个序列是不合法的,必定满足某些结论,我们不妨猜测一下首先如果和为\(P\)的倍数,必定不合法然后手玩几个可以发现,最极限的情况是\(P-1\)个\(1\;+\;\)\(b_i\;+\;\)\(P-b_i\)如果在这个情况下再加一个\(1\),就爆了其中\(1\)可以替......
  • CF689题解
    CF689CodeforcesRound361(Div.2)CF689AlinkCF689A题意题目描述迈克在海滩游泳时不小心将手机放入水中。他买了一个带有老式键盘的手机。键盘只有十个数字大小的键,位于以下方式:1234567890联系人与他的旧手机一起消失了,他现在只能记住他的手指......
  • 商家转账到零钱全攻略:开通、使用、区别与常见问题解答
    一、商家转账到零钱功能介绍微信作为中国最受欢迎的社交平台之一,其支付功能也相当强大。其中,商家转账到零钱功能可以让商家直接将款项转入用户的微信零钱,方便快捷。本文将详细介绍商家转账到零钱的功能、开通条件、使用方法以及常见问题解答。二、商家转账到零钱场景说明商家转......
  • axios(ajax)发送请求响应码200,但获取不到数据,无法加载响应数据: No datafound for res
    问题截图:没有响应数据控制台报错其实是由于浏览器的跨域资源共享(CORS)策略导致,前后端跨域请求是不行的。什么是域,看页面的url,比如https://www.baidu.com/下的网页都是属于baidu.com这个域。如果你是和我一样是从本地文件打开html的方式来调试ajax,那么一定会出现这个问题,因为本......
  • CF1846E2 Rudolf and Snowflakes (hard version) 题解
    题意:\(T\)\((\)\(1\)\(\le\)\(T\)\(\le\)\(10^4\)\()\)组询问:是否存在一个满\(k\)(\(k\)\(\ge\)\(2\)\()\)叉树节点数恰好为\(n\)\((\)\(1\)\(\le\)\(n\)\(\le\)\(10^{18}\)\()\),且深度\(depth\)至少为\(2\)。思路:满$k$......
  • luogu2839题解
    [国家集训队]middle题目分析代码如下。#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;typedefunsignedlonglongull;constintMAXN=2e4+10;intx,n,Q,a[MAXN],q[6],root[MAXN],b[MAXN],tot;vector<int>locp[MAXN];structSegmentTreeNode{......
  • CF1827C Palindrome Partition 题解
    题目链接点击打开链接题目解法首先考虑一个朴素的\(dp\)令\(f_i\)表示以\(i\)结尾的合法子串的个数为了不重不漏,我们令\(le_i\)表示以\(i\)为右端点,离\(i\)最近的偶回文串的左端点,然后不难得到转移为\(f_i=f_{le_i-1}+1\)为什么不会漏?考虑以\(i\)为右端点,且比......
  • NOIP2000提高组真题解析
    NOIP2000提高组真题解析第一题进制转换题目链接解析首先,我们知道对于10进制数x转2进制数,使用的算法是:求出x%2令x=x/2不断执行1,2,直至x为0,然后倒序输出步骤1的结果。一般可以用数组存步骤1的结果倒序输出或者使用dfs回溯回来再输出。对于负数的情况,比如\(-7=1*(-2)^3......