Codeforces Round #835 (Div. 4)

A. Medium Number

#include<bits/stdc++.h>
using namespace std;


int read(){
    int x = 0 , f = 1 , ch = getchar();
    while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
    if( ch == '-' ) f = -1 , ch = getchar();
    while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
    return x * f;
}

void solve(){
    vector<int>v(3);
    for( int & i : v)
        i = read();
    std::sort(v.begin(), v.end());
    cout << v[1] << "\n";
}


int main(){
    for( int t = read(); t ; t -- )
        solve();

}

B. Atilla's Favorite Problem

#include<bits/stdc++.h>
using namespace std;

int read(){
    int x = 0 , f = 1 , ch = getchar();
    while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
    if( ch == '-' ) f = -1 , ch = getchar();
    while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
    return x * f;
}

void solve(){
    int n = read();
    string s;
    cin >> s;
    int res = 0;
    for( auto i : s )
        res = max( res , i - 'a' + 1 );
    cout << res << "\n";
}


int main(){
    for( int t = read(); t ; t -- )
        solve();

}

C. Advantage

赛时我的做法是求区间最值,所以自然而然的想到了ST

#include<bits/stdc++.h>
using namespace std;


int read(){
    int x = 0 , f = 1 , ch = getchar();
    while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
    if( ch == '-' ) f = -1 , ch = getchar();
    while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
    return x * f;
}


const int N = 2e5+5 , logN = 20;
int n , a[N] , log_2[N];
int f[N][logN + 5];

int getMax( int l , int r ){
    if( r < l ) return INT_MIN;
    int s = log_2[ r - l + 1 ];
    return max( f[l][s] , f[ r - (1<<s) + 1 ][s] );
}

void solve(){
    n = read();
    for( int i = 1 ; i <= n ; i ++ ) a[i] = read();
    log_2[0] = -1;
    for( int i = 1 ; i <= n ; i ++ )
        f[i][0] = a[i] , log_2[i] = log_2[i>>1] + 1;
    for( int j = 1 ; j <= logN ; j ++ )
        for( int i =1 ; i + ( 1 << j ) - 1 <= n ; i ++ )
            f[i][j] = max( f[i][j-1] , f[ i+(1<<j-1) ][j-1] );

    for( int i = 1 ; i <= n ; i ++ )
        printf("%d " , a[i] - max(getMax( 1 , i-1 ) , getMax( i+1 , n ) ) );

    printf("\n");
    return;
}


int main(){
    for( int t = read(); t ; t -- )
        solve();

}

然后发现只要求一下最大值和次大值即可

#include<bits/stdc++.h>
#define int long long
using namespace std;

int read() {...}

void solve(){
    int n = read() , a = INT_MIN , b = INT_MIN;
    vector<int> v(n);
    for( auto &i : v ) i = read();
    for( auto i : v ) {
        if( i >= a ) b = a , a = i;
        else if( i > b ) b = i;
    }
    for( auto i : v ){
        if( i == a ) printf("%lld " , i-b );
        else printf("%lld " , i - a );
    }
    printf("\n");
    return;
}


int32_t main() {
    for( int t = read() ; t ; t -- )
        solve();
    return 0;
}

D. Challenging Valleys

为了方便计算,在开头和结尾分别加上两个无穷大,然后\(O(n)\)的找一下谷的个数就好

#include<bits/stdc++.h>
using namespace std;


int read(){...}

void solve(){
    int n = read() , flag = 0;
    vector<int> v;
    v.push_back(INT_MAX);
    for( int i = 1 , x ; i <= n ; i ++ ) x = read() , v.push_back(x);
    v.push_back(INT_MAX);
    for( int l = 1 , r ; l <= n; l ++ ){
        if( v[l-1] <= v[l] ) continue;
        for( r = l ; v[r]== v[l] && r <= n ; r ++ );
        r --;
        if( v[r] < v[r+1] ) flag ++;
        l = r;
    }
    printf( (flag == 1 ? "YES\n" : "NO\n") );
    return;
}


int main(){
    for( int t = read(); t ; t -- )
        solve();

}

E. Binary Inversions

首先可以倒序枚举统计一下再不进行任何操作时逆序对的数量

然后枚举操作哪一位就好了,枚举前先对序列求一下前缀和记为\(b_i\)

如果这一位是1 ,删后0也就是-( (n - i) - (b[n] - b[i]) ),加前1也就是+b[i-1]化简得-n+i+b[n]-1

如果这一位是0,删前1也就是-b[i-1],加后0,也就是+( (n-i) - (b[n]-b[i]) )化简得n-i-b[n]

通过化简我们发现其实不用前缀和只需要知道一共有多少1即可

#include<bits/stdc++.h>
#define int long long
using namespace std;


int read(){
    int x = 0 , f = 1 , ch = getchar();
    while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
    if( ch == '-' ) f = -1 , ch = getchar();
    while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
    return x * f;
}

const int N = 2e5+5;
int a[N] , b[N];

void solve(){
    int n = read() , cnt = 0, res = 0 , ans;
    for( int i = 1 ; i <= n ; i ++ ) a[i] = read() , b[i] = b[i-1] + a[i];
    for( int i = n ; i >= 1 ; i -- ){
        if( a[i] == 0 ) cnt ++;
        else res += cnt;
    }
    cnt = n - cnt;
    ans = res;
    for( int i = 1 ; i <= n ; i ++ ){
        if( a[i] == 0 )
            ans = max( ans , res + n - i - cnt );
        else
            ans = max( ans , res - n + i + cnt - 1 );
    }
    cout << ans << "\n";

}

int32_t main(){
    for( int t = read(); t ; t -- )
        solve();
}

F. Quests

因为要尽可能的多选,所以要尽可能的选当前能选的最大值,所以把序列排一个序,然后求前缀和。

然后二分一下最大的k就好,并且把二分的上届设为大于d 的值,这样如果二分的结果是大于等于d的话,答案就是Infinity

#include<bits/stdc++.h>
#define int long long
using namespace std;

int read(){...}

const int N = 2e5+50;
int a[N] , f[N] , n , c , d , sum;

bool check( int k ){
    k ++;
    int tt = a[k] * ( d / k ) + a[ d % k ];
    return tt >= c;
}

void solve(){
    n = read() , c = read() , d = read() , sum;
    memset( a , 0 , sizeof(a) );
    for( int i = 1 ; i <= n  ; i ++ ) a[i] = read();
    sort( a+1 , a+1+n , greater<int>() );
    for( int i = 1 ; i <= max( d , n )+10 ; i ++ ) a[i] += a[i-1];
    int l = 0 , r = d+10, res = -1;
    while( l <= r ){
        int mid = ( l + r ) >> 1;
        if( check( mid ) ) res = mid , l = mid + 1;
        else r = mid - 1;
    }
    if( res == -1 ) printf("Impossible\n");
    else if( res >= d ) printf("Infinity\n");
    else printf("%lld\n" , res );
}

int32_t main(){
    for( int t = read(); t ; t -- )
        solve();

}

G. SlavicG's Favorite Problem

这题其实就是先求出从a出发到所有点的异或和,在求出从b出发到所有点的异或和,然后判断是否有相同的异或和就好。

所以很自然想到用 set 来存a到所有点的异或和,然后在从b进行 dfs 的时候判断即可。

注意的坑点从b出发的点判断是否在 set 中的时候要b本身特判掉,并且从 a出发如果到达b则不能继续搜索下去了,并且如果异或和为0就要直接结束,因为可以不进行任何一跳。

#include<bits/stdc++.h>
#define int long long
using namespace std;


int read(){
    int x = 0 , f = 1 , ch = getchar();
    while( (ch < '0' || ch > '9') && ch != '-' ) ch = getchar();
    if( ch == '-' ) f = -1 , ch = getchar();
    while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
    return x * f;
}

const int N = 1e5+5;

typedef pair<int,int> PII;
int a , b , n , flag;
bool vis[N];
set<int> all;
vector<PII> e[N];

void dfs( int u , int val){
    vis[u] = true;
    if( u != b ) all.insert( val );
    else {
        if( val == 0 ) flag = 1;
        return;
    }
    for( auto [ v , w ] : e[u] ){
        if( vis[v] ) continue;
        dfs( v , val ^ w );
    }
    return;
}

bool Dfs( int u , int val ){
    vis[u] = true;
    if( u != b && all.count( val ) ) {
        return true;
    }
    for( auto [ v , w ] : e[u] ){
        if( vis[v] ) continue;
        if( Dfs( v , val ^ w ) ) return true;
    }
    return false;
}
void solve(){
    n = read() , a = read() , b = read() , flag = 0;
    fill( e+1 , e+1+n , vector<PII> () );
    fill( vis+1 , vis+1+n , false );
    for( int i = 1 , u , v , w ; i < n ; i ++ )
        u = read() , v = read() , w = read() ,
        e[u].emplace_back( v , w ) , e[v].emplace_back( u , w );
    all.clear();
    dfs( a , 0 );
    if( flag ){
        printf("YES\n");
        return;
    }
    fill( vis+1 , vis+1+n , false );
    printf( (Dfs( b ,0 ) == true ? "YES\n" : "NO\n") );
}


int32_t main(){
    for( int t = read(); t ; t -- )
        solve();

}
posted @ 2022-11-22 15:28  PHarr  阅读(121)  评论(0编辑  收藏  举报