Codeforces Round #576 (Div. 2) 题解

7.30号的cf,很久没打cf了,决定打一下,果然掉了10分。。。幸好还是蓝名。。。打完第二天就发了高烧也是无语。。。吃药在宿舍躺尸两天,决定把题解写下。。

A. City Day
题目很简单,不过英文有点绕。就是找到第一个符合的点,这个点是前面x个的值都比它大,后面y个的值都比它大。相当于一个凹点。当然,前面x可以不存在,后面y个也可以有不存在的。
代码如下:

#include<bits/stdc++.h>
 
using namespace std;
 
int main(void){
    int N,x,y;
    scanf("%d%d%d",&N,&x,&y);
    vector<int> vec(N+4);
    for(int i=1;i<=N;++i){
        scanf("%d",&vec[i]);
    }
    int res = 0;
    for(int i=1;i<=N;++i){
        bool isok = true;
        for(int j=i-1;j>=i-x && j >= 1;--j){
 
            if(vec[j] <= vec[i]){
                isok = false;
                break;
            }
        }
        for(int j=i+1;j<=i+y && j <= N;++j){
            if(vec[j] <= vec[i]){
                isok = false;
            }
        }
        if(isok){
            printf("%d\n",i);
            break;
        }
    }
 
    return 0;
}

B. Water Lily
在这里插入图片描述
如图,可以求的V = (L*L-H*H)/(2*H),不确定会不会爆double,我用的long double
代码略

C. MP3
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
One common way of digitalizing sound is to record sound intensity at particular time moments. For each time moment intensity is recorded as a non-negative integer. Thus we can represent a sound file as an array of n non-negative integers.

If there are exactly K distinct values in the array, then we need k=⌈log2K⌉ bits to store each value. It then takes nk bits to store the whole file.

To reduce the memory consumption we need to apply some compression. One common way is to reduce the number of possible intensity values. We choose two integers l≤r, and after that all intensity values are changed in the following way: if the intensity value is within the range [l;r], we don’t change it. If it is less than l, we change it to l; if it is greater than r, we change it to r. You can see that we lose some low and some high intensities.

Your task is to apply this compression in such a way that the file fits onto a disk of size I bytes, and the number of changed elements in the array is minimal possible.

We remind you that 1 byte contains 8 bits.

k=⌈log2K⌉ is the smallest integer such that K≤2k. In particular, if K=1, then k=0.

Input
The first line contains two integers n and I (1≤n≤4⋅105, 1≤I≤108) — the length of the array and the size of the disk in bytes, respectively.

The next line contains n integers ai (0≤ai≤109) — the array denoting the sound file.

Output
Print a single integer — the minimal possible number of changed elements.

Examples
inputCopy
6 1
2 1 2 3 4 3
outputCopy
2
inputCopy
6 2
2 1 2 3 4 3
outputCopy
0
inputCopy
6 1
1 1 2 2 3 3
outputCopy
2
Note
In the first example we can choose l=2,r=3. The array becomes 2 2 2 3 3 3, the number of distinct elements is K=2, and the sound file fits onto the disk. Only two values are changed.

In the second example the disk is larger, so the initial file fits it and no changes are required.

In the third example we have to change both 1s or both 3s.

这题费工夫了。。自己当时理解傻逼了,结果到最后才过。。。自己英语真是有问题。。。

题意:
对于一首歌,可以用一个数组来去存储。如果数组中,不同的个数是K,那么每个数组中的值都需要 k=[log2K]bitsk = [\log_2 K] bits 你可以把歌曲压缩,即把数组的数都变到[L,R]这个区间。问你在给定数组下,I Bytes下,需要最少的改变次数。
1 Bytes = 8 bits.

思路:
首先,堆数组进行处理,处理为这种形式 {数值,次数},存入vec,其不同的个数为Size.
当前需要的最大存储量即为 pow(2,Size)*n bits 和 8*I进行比较,如果前者小,那么改变0个(即不同改变)就可以存储。如果后者小,那么就需要进行压缩。求的当前的
K=pow(2,8I/N)K = pow(2,8*I/N) 注意这里一定要先比较,因为8*I/N之后的值仍然可能很大,如果不比较一定会溢出(pp里面竟然没有这组数组,真是太弱了。。我同学竟然靠这个叉了两个人。。。) 然后当前的K就是要留下的不同的数组,就变成长度为K的数组,最大值和为多少的问题。利用前缀和扫描一遍就可以了。
代码如下:

#include<bits/stdc++.h>
 
using namespace std;
typedef long long ll;
const int MAX = 4e5+10;
ll a[MAX];
int sum[MAX];
ll N,I;
 
class Node{
public:
    int v;
    int num;
    Node(int _v = 0,int _num = 0):v(_v),num(_num){}
};
 
vector<Node> vec;
int main(void){
 
    scanf("%lld%lld",&N,&I);
    for(int i=1;i<=N;++i){
        scanf("%lld",&a[i]);
    }
    sort(a+1,a+1+N);
    vec.clear();
    int last = a[1];
    int Count = 1;
    for(int i=2;i<=N;++i){
        if(a[i] == last){
            Count++;
        }
        else{
            vec.push_back(Node(last,Count));
            last = a[i];
            Count = 1;
        }
    }
    vec.push_back(Node(last,Count));
    for(int i=0;i<vec.size();++i){
        if(i == 0)
            sum[i] = 0;
        else
            sum[i] = sum[i-1]+vec[i].num;
    }
    ll k = 8*I/N;
    int nowK = ceil(log2((int)vec.size()));
 
    if(nowK <= k){
        printf("%d\n",0);
        return 0;
    }
    int MaxK = pow(2,k);
    int Maxleave = 0;
    for(int i=0;i+MaxK <= vec.size();++i){
        if(i == 0){
            Maxleave = max(Maxleave,sum[i+MaxK-1]);
        }
        else{
            Maxleave = max(Maxleave,sum[i+MaxK-1]-sum[i-1]);
        }
   //     printf("M = %d\n",Maxleave);
    }
    printf("%d\n",N-Maxleave);
 
 
    return 0;
}

D. Welfare State
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
There is a country with n citizens. The i-th of them initially has ai money. The government strictly controls the wealth of its citizens. Whenever a citizen makes a purchase or earns some money, they must send a receipt to the social services mentioning the amount of money they currently have.

Sometimes the government makes payouts to the poor: all citizens who have strictly less money than x are paid accordingly so that after the payout they have exactly x money. In this case the citizens don’t send a receipt.

You know the initial wealth of every citizen and the log of all events: receipts and payouts. Restore the amount of money each citizen has after all events.

Input
The first line contains a single integer n (1≤n≤2⋅105) — the numer of citizens.

The next line contains n integers a1, a2, …, an (0≤ai≤109) — the initial balances of citizens.

The next line contains a single integer q (1≤q≤2⋅105) — the number of events.

Each of the next q lines contains a single event. The events are given in chronological order.

Each event is described as either 1 p x (1≤p≤n, 0≤x≤109), or 2 x (0≤x≤109). In the first case we have a receipt that the balance of the p-th person becomes equal to x. In the second case we have a payoff with parameter x.

Output
Print n integers — the balances of all citizens after all events.

Examples
inputCopy
4
1 2 3 4
3
2 3
1 2 2
2 1
outputCopy
3 2 3 4
inputCopy
5
3 50 2 1 10
3
1 2 0
2 8
1 3 20
outputCopy
8 8 20 8 10
Note
In the first example the balances change as follows: 1 2 3 4 → 3 3 3 4 → 3 2 3 4 → 3 2 3 4

In the second example the balances change as follows: 3 50 2 1 10 → 3 0 2 1 10 → 8 8 8 8 10 → 8 8 20 8 10

这个题,感觉比C题要简单。套个板子就能过了。
N个数的数组,两种操作。
- 1 p x :把p位置的数改为x
- 2 x:把小于x的数修改为x
线段树裸题了。。维护区间最小值就可以了,注意push_down的时候的修改。

#include<bits/stdc++.h>
 
using namespace std;
typedef long long ll;
 
const int MAX = 2e5+10;
 
#define lson (r<<1)
#define rson (r<<1|1)
int a[MAX],N;
class Node{
public:
    int l,r;
    int val,lazy;
    Node(){
        l = r = val = lazy = 0;
    }
    int mid(){
        return (l+r)/2;
    }
}tree[MAX<<2];
 
void push_up(int r){
    tree[r].val = min(tree[lson].val,tree[rson].val);
}
 
void push_down(int r){
    if(tree[r].lazy){
        //注意这里lazy标记是向下一代传递的,所以,这里左右儿子的值要用父亲的lazy来更新。
        tree[lson].val = max(tree[lson].val,tree[r].lazy);
        tree[rson].val = max(tree[rson].val,tree[r].lazy);
        
        tree[lson].lazy = max(tree[r].lazy,tree[lson].lazy);
        tree[rson].lazy = max(tree[r].lazy,tree[rson].lazy);
        tree[r].lazy = 0;
    }
}
void build_tree(int r,int L,int R){
    tree[r].l = L;tree[r].r = R;
    tree[r].lazy = 0;
    if(L == R){
        tree[r].val = a[L];
        return;
    }
    int mid = tree[r].mid();
    build_tree(lson,L,mid);
    build_tree(rson,mid+1,R);
    push_up(r);
}
void update_point(int r,int p,int v){
    if(tree[r].l == tree[r].r && p == tree[r].l){
        tree[r].val = v;
        return;
    }
    push_down(r);
    int mid = tree[r].mid();
    if(p <= mid)
        update_point(lson,p,v);
    else
        update_point(rson,p,v);
    push_up(r);
}
void update_interval(int r,int val){
    if(tree[r].val >= val)  return;
    tree[r].val = val;
    tree[r].lazy = max(tree[r].lazy,val);
}
 
int query(int r,int p){
    if(tree[r].l == tree[r].r && tree[r].l == p)
        return tree[r].val;
    push_down(r);
    int mid = tree[r].mid();
    if(p <= mid)
        return query(lson,p);
    else
        return query(rson,p);
}
int main(void){
    scanf("%d",&N);
    for(int i=1;i<=N;++i)
        scanf("%d",&a[i]);
    build_tree(1,1,N);
    int Q;
    scanf("%d",&Q);
    int op,p,x;
    for(int i=1;i<=Q;++i){
        scanf("%d",&op);
        if(op == 1){
            scanf("%d%d",&p,&x);
            update_point(1,p,x);
        }
        else{
            scanf("%d",&x);
            update_interval(1,x);
        }
    }
    for(int i=1;i<=N;++i){
        printf("%d",query(1,i));
        printf("%c",(i==N?'\n':' '));
    }
 
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章