Educational Codeforces Round 22
A. The Contest
想一想就知道,提交的时间无所谓,所以我们选择全部做完后的第一个时间间隔提交即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
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;
}
int32_t main(){
int n = read() , res = INT_MAX , cnt = 0;
for( int x ; n ; n -- )
x = read() , cnt += x;
int m = read();
for( int l , r ; m ; m -- ){
l = read() , r = read();
if( r < cnt ) continue;
res = max( l , cnt );
break;
}
if( res == INT_MAX ) res = -1;
cout << res << "\n";
return 0;
}
B. The Golden Age
根据乘法原理就可以知道,unlucky 的数字其实不多,最多应该是\(\log_{2}10^{18}\times\log_3 10^{18}\)。我们枚举出所有的数字然后计算下区间大小取最大值即可。
#include <bits/stdc++.h>
using namespace std;
#define int __int128
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;
}
int32_t main(){
int x , y , l , r;
x = read() , y = read() , l = read() , r = read();
set<int> unlucky;
for( int a = 1 ; a <= r ; a *= x )
for( int b = 1 ; a + b <= r ; b *= y )
unlucky.insert( a + b );
int res = 0 , last = l;
for( auto i : unlucky ){
if( i < l ) continue;
if( i > r ) break;
res = max( res , i - last );
last = i + 1 ;
}
res = max( res , r - last + 1 );
cout << (long long)res << "\n";
return 0;
}
C. The Tag Game
Bob 的策略其实就是尽可能的远离 Alice ,这样的话,Bob 的选择其实只有三种
- 向父节点走
- 向子树中最深的方向走
- 待在原地
不过要保证的是 Bob在向父节点走的过程中不能和 Alice相遇,这样的话,实际上就是让 Bob沿着1到x的路径最多走到一半,然后在向最深的叶子节点走。这样的话代价就是根到最深的叶子点的距离的二倍。
#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;
}
vector<vector<int>> e;
vector<int> dep , maxdep , fa;
void dfs( int x ){
maxdep[x] = dep[x];
for( auto y : e[x] ){
if( y == fa[x] ) continue;
fa[y] = x , dep[y] = dep[x] + 1;
dfs(y);
maxdep[x] = max( maxdep[x] , maxdep[y] );
}
return;
}
int main() {
int n = read() , s = read();
e = vector<vector<int>>(n+1);
dep = vector<int>(n+1);
fa = vector<int>(n+1);
maxdep = vector<int>(n+1);
for( int i = 1 , x , y ; i < n ; i ++ ){
x = read() , y = read();
e[x].push_back(y) , e[y].push_back(x);
}
fa[1] = -1;
dfs( 1 );
int res = maxdep[s] , cnt = 0;
while(true){
s = fa[s] , cnt ++;
if( dep[s] <= cnt ) break;
res = max( res, maxdep[s] );
}
cout << res * 2 << "\n";
return 0;
}
D. Two Melodies
设状态f[i][j]
为一个串选到a[i]
一个串选到b[i]
的最优解。
很容易就能想到\(O(N^3)\)的转移
for( int i = 0 ; i <= n ; i ++ )
for( int j = 0 ; j < i ; j ++ ){
if( i != 0 ) f[i][j] = max( f[i][j] , f[0][j] + 1 );
if( j != 0 ) f[i][j] = max( f[i][j] , f[i][0] + 1 );
for( int k = 1 ; k < i ; k ++ )
if( abs( a[i] - a[k] ) == 1 || a[i] % 7 == a[k] % 7 )
f[i][j] = max( f[i][j] , f[k][j] + 1 );
for( int k = 1 ; k < j ; k ++ )
if( abs( a[j] - a[k] ) == 1 || a[j] % 7 == a[k] % 7 )
f[i][j] = max( f[i][j] , f[i][k] + 1);
res = max( res , f[i][j] );
}
其实我们注意到k
的求解是可以优化的,我们用两个桶来维护所有可能的a[k]
值的最优解。
#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;
}
int main(){
int n = read() , res = 0;
vector<int> a(n+1);
for( int i = 1 ; i <= n ; i ++ ) a[i] = read();
vector<vector<int>> f( n+1 , vector<int>(n+1 , LLONG_MAX) );
for( int i = 0 ; i <= n ; i ++ ){
vector<int> pre( 100000+1) , mod(7);
for( int j = 1 ; j < i ; j ++ )
pre[ a[j] ] = max( pre[ a[j] ] , f[i][j] ),
mod[ a[j] % 7 ] = max( mod[a[j] % 7] , f[i][j] );
for( int j = i + 1 ; j <= n ; j ++ ){
f[i][j] = max( pre[a[j]-1] , pre[a[j]+1] ) + 1;
f[i][j] = max( f[i][j] , mod[a[j]%7] + 1 );
f[i][j] = max( f[i][j] , f[i][0] + 1 );
f[j][i] = f[i][j];
pre[ a[j] ] = max( pre[ a[j] ] , f[i][j] );
mod[ a[j] % 7 ] = max( mod[ a[j] % 7 ] , f[i][j] );
res = max( res , f[i][j] );
}
}
cout << res << "\n";
return 0;
}