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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章