CodeTON Round 6 (Div. 1 + Div. 2)( A-D )
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的分配
那么先跑一个cost随距离单增的数组出来(cost高,距离又近的显然不会使用)
实行以下策略:
不断寻找相同次数下,选最远的,将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 ;
}