CodeTON Round 6 (Div. 1 + Div. 2)( A-D )

发布时间 2023-09-19 14:22:09作者: 蓝银杏-SSW

A. MEXanized Array

下次还得得签快一点,嘉心糖4分就过了


思路

一个简单的讨论 n k x 之间关系就行

完整代码

#include<bits/stdc++.h>
using namespace std ; 
#define ll long long
inline int read(){
    int s=0,w=1 ; char g=getchar() ; while( g>'9'||g<'0' ){if(g=='-')w=-1;g=getchar() ; }
    while( g>='0' && g <='9' )s=s*10+g-'0',g=getchar() ; return s*w ; 
} 
#define ll long long
void solve(){
    int n = read() , k = read() , x = read() ; 
    if( n < k ){
        cout<<-1<<endl ; return ; 
    }
    if( x > k ){
        ll sum = 0 ; 
        for( int i = 0 ; i < k ; ++i )sum += min( i , k-1 ) ; 
        for( int i = k ; i < n ; ++i )sum += x ; 
        cout<<sum<<endl ; return ; 
    }
    else if( x < k-1 ){
        cout<<-1<<endl ; return ; 
    }
    else{
        ll sum = 0 ; if( x == k )x-- ; 
        for( int i = 0 ; i < n ; ++i )sum += min( i , x ) ; 
        cout<<sum<<endl ; return ; 
    }
}
int main(){
    int t = read()  ; 
    while(t--)solve() ; 
    return 0 ; 
}

B. Friendly Arrays

赛后发现这题慢了的原因是分开写了一样的东西


思路

奇偶性+或运算的性质
因为最后要异或起来,所以不难发现:

奇数: Min = 全部或起来 Max = 不动
偶数: Max = 全部或起来 Min = 不动

完整代码

#include<bits/stdc++.h>
using namespace std ; 
#define ll long long
inline int read(){
    int s=0,w=1 ; char g=getchar() ; while( g>'9'||g<'0' ){if(g=='-')w=-1;g=getchar() ; }
    while( g>='0' && g <='9' )s=s*10+g-'0',g=getchar() ; return s*w ; 
} 
#define ll long long
const int MAXN = 200005 ;  
int a[MAXN] , b[MAXN] ; 
void solve(){
    int n = read() , m = read() ;
    for( int i = 1 ; i <= n ; ++i )a[i] = read() ; 
    for( int j = 1 ; j <= m ; ++j )b[j] = read() ; 
    int tmp = 0  , ans1 = 0 , ans2 = 0  ; 
    for( int j = 1 ; j <= m ; ++j )tmp |= b[j] ; 
    for( int i = 1 ; i <= n ; ++i )ans1 ^= (a[i]|tmp) , ans2 ^= a[i] ; 
    if(n%2)cout<<ans2<<" "<<ans1<<endl ; 
    else cout<<ans1<<" "<<ans2<<endl ; 
}
int main(){
    int t = read()  ; 
    while(t--)solve() ; 
    return 0 ; 
}

C. Colorful Table

傻逼ssw愚蠢地放错了位置,重置了l , r ,被ftp给叉了


思路

其实考虑到小的会覆盖大的。那我们从小到大考虑,倘若处理数 3 的时候 , 如果两侧有 1 2 占据满了所有位置,那么3所占的矩形周围就会被 1 2 占满。

翻译一下:我们用 L r 维护当前左右两侧据当前处理数最远的位置(第一个非小于的位置)

完整代码

#include<bits/stdc++.h>
using namespace std ; 
#define ll long long
inline int read(){
    int s=0,w=1 ; char g=getchar() ; while( g>'9'||g<'0' ){if(g=='-')w=-1;g=getchar() ; }
    while( g>='0' && g <='9' )s=s*10+g-'0',g=getchar() ; return s*w ; 
} 
#define ll long long
const int MAXN = 100005 ;  
vector<int>a[MAXN] ; bool used[MAXN] ; 
void solve(){
    int n = read() , k = read() ; 
    //cout<<n<<" --------- "<<k<<endl ;
    for( int i = 0 ; i <= k ; ++i )a[i].clear() ; 
    for( int i = 0 ; i <= k ; ++i )a[i].push_back(0) ; 
    for( int i = 1 ; i <= n ; ++i ){
        int x = read() ; a[x][0]++ ; used[i] = false ; 
        a[x].push_back(i) ; 
    }//cout<<n<<" --------- "<<k<<endl ;
    int l = 0 , r = n+1 ;
    for( int i = 1 ; i <= k ; ++i ){
        int ma = -10000000 , mi = 100000000 ; 
        while( used[l+1] && l < r )l++ ; while( used[r-1] && l < r )r-- ; 
        for( int j = 1 ; j <= a[i][0] ; ++j ){
            ma = max( ma , a[i][j] ) , mi = min( mi , a[i][j] ) ; 
            used[ a[i][j] ] = true ; 
        }
        if( ma == -10000000 || mi == 100000000 ){
            cout<<0<<" "  ; continue ; 
        }
        cout<<(r-l-1)*2<<" " ; 
    }
    cout<<endl ;
}
int main(){
    int t = read()  ; 
    while(t--)solve() ; 
    return 0 ; 
}

D. Prefix Purchase

嘉心糖:小学数学不及格,除法都不会


思路

其实考虑这么一个思路:我一定在能选相同次数下,选最远的 。 那考虑res的分配

实行以下策略:

不断寻找相同次数下,选最远的,将k减去消耗,将剩下的cost都降低(记录一个base_cost),不断重复这个过程直至跑完即可

完整代码

#include<bits/stdc++.h>
using namespace std ; 
#define ll long long
inline int read(){
    int s=0,w=1 ; char g=getchar() ; while( g>'9'||g<'0' ){if(g=='-')w=-1;g=getchar() ; }
    while( g>='0' && g <='9' )s=s*10+g-'0',g=getchar() ; return s*w ; 
} 
#define ll long long
const int MAXN = 200005 ;  
int c[MAXN]  ; 
int cost[MAXN] , id[MAXN] , tot = 0 ; 
void solve(){
    int n = read() ,  tot = 0 ; 
    for( int i = 1 ; i <= n ; ++i )c[i] = read() ;
    int k = read() ;
    int lim = 1000000005 ; 
    for( int i = n ; i ; --i ){
        if( lim <= c[i] )continue ; 
        lim = min( lim , c[i] ) ;
        id[++tot] = i ; cost[tot] = lim ; 
    } 
    int base = 0 , bcost = 0 ; lim = tot  ; 
    while( base < n ){
        int t = k/( cost[lim]-bcost ) ; 
        for( int i = lim ; i ; i-- ){
            if( k/(cost[i]-bcost) == t ){
                lim = i ; 
            }
        }
        for( int i = base+1 ; i <= id[lim] ; ++i )cout<<t<<" " ; 
        k -= t*(cost[lim]-bcost ) ; base = id[lim] ; bcost = cost[lim] ; lim-- ;
    }
    cout<<endl ; 
}
int main(){
    int t = read()  ; 
    while(t--)solve() ; 
    return 0 ; 
}