牛客小白月赛71
A 猫猫与广告
#include <bits/stdc++.h>
using namespace std;
int32_t main(){
int a , b , c , d ;
cin >> a >> b >> c >> d;
if( a > b ) swap(a , b);
if( c > d ) swap( c , d );
if( a <= c && b <= d ) cout << "YES\n";
else cout << "NO\n";
return 0;
}
B 猫猫与密信
#include <bits/stdc++.h>
using namespace std;
int32_t main(){
string s;
cin >> s;
if ( s.find("love") != -1 )cout << "YES\n";
else if (s.find("lov") != -1) cout << "YES\n";
else if (s.find("loe") != -1) cout << "YES\n";
else if (s.find("lve") != -1) cout << "YES\n";
else if (s.find("ove") != -1) cout << "YES\n";
else cout << "NO\n";
return 0;
}
C 猫猫与数列
其实就是按照题目操作就好了,但是精度问题把我整麻了,最后又 python 来解决了,感觉和电科校赛异曲同工了。
m = 10 ** 18
def power( x , y ) :
ans = 1
while( y > 0 ):
# print( x , y , ans)
if( y % 2 == 1 ) :
ans = ans * x
if( ans > m ) :
# print( ans , m , " cnt")
return ans
y = y // 2
x = x * x
if( y > 0 and x > m ) :
return x
return ans
a = list(map( int, input().split(' ') ))
while a[-1] <= m :
x = power( a[-2] , a[-1])
a.append( x )
cnt = 0
for i in a :
if( i <= m ) :
cnt += 1
else :
print( cnt )
D 猫猫与主人
看了看答案的做法是离线回答询问。其实感觉还是蛮不好想的。
我的做法是首先把人按照\(d_i\)从小到大排序,对于每一只猫可以二分出最大的\(r\)满足\(a_i\ge d_r\),这样的话对于\(j\in[1,r]\)都满足了\(a_i\ge d_j\)现在要找是否存在\(j\)满足\(b_j\ge c_i\),满足的条件可以简化为\(\max(b_j)\)满足,这样的话实际上就是求区间最值,因为没有修改所以我使用 ST 表实现。
#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;
}
const int N = 2e5+5 , logN = 20;
int a[N] , c[N] , log_2[N] , f[N][logN+5];
pair<int,int> person[N];
int search( int l , int r ){
int s = log_2[ r - l + 1 ];
return max( f[l][s] , f[ r-(1<<s) + 1 ][s] );
}
int32_t main(){
int n = read() , m = read();
for( int i = 1 ; i <= n ; i ++ ) a[i] = read();
for( int i = 1 ; i <= n ; i ++ ) c[i] = read();
for( int i = 1 ; i <= m ; i ++ ) person[i].second = read();
for( int i = 1 ; i <= m ; i ++ ) person[i].first = read();
sort( person +1 , person+1+m);
log_2[0] = -1;
for( int i = 1 ; i <= m ; i ++ )
f[i][0] = person[i].second , log_2[i] = log_2[i>>1] + 1;
for( int j = 1 ; j <= logN ; j ++ )
for( int i = 1; i + (1<<j) - 1 <= m ; i ++ )
f[i][j] = max( f[i][j-1] , f[i+(1<<j-1) ][j-1] );
for( int i = 1 ; i <= n ; i ++ ){
int l = 1 , r = m , mid , ans = 0;
while( l <= r ){
mid = ( l + r ) >> 1;
if( person[mid].first <= a[i] ) ans = mid , l = mid + 1;
else r = mid - 1;
}
if( ans == 0 ) {
printf("-1 ");
continue;
}
int t = search( 1 , ans );
if( t >= c[i] ) printf("%lld " , t );
else printf("-1 ");
}
return 0;
}
E 猫猫与数学
令\(a > b\),根据更相减损术\(\gcd( a + c , b + c ) = \gcd( a - b , a + c )\)
现在要求最小的\(c\)满足$\gcd(a-b,a+c) \ne 1 $
考虑到\(a-b\)这个数字是\(10^{14}\),说明\(a-b\)的因子\(d\)最多有\(10^7\)级别个,我们可以枚举\(d\)使得\(\gcd(a-b,a+c)=d\)则要求\(a+c\)是\(d\)的倍数。可以\(O(1)\)的算出最小的\(c\),这样复杂度就可以接受。
#include <bits/stdc++.h>
using namespace std;
#define int long long
int32_t main() {
int a , b , d , res = 1e18;
cin >> a >> b;
if( a < b ) swap( a , b );
d = a - b;
if( d == 1 ){
printf("-1\n");
return 0;
}else if( d == 0 ){
if( a == 1 ) printf("1\n");
else printf("0\n");
return 0;
}
auto check = [&]( int x ){
if( x == 1 ) return;
if( a % x == 0 ) res = min( res , 0ll );
else res = min( res , x - a % x );
};
for( int i = 1 , n = sqrt(d) ; i <= n ; i ++ ){
if( d % i ) continue;
check(i) , check(d/i);
}
printf("%lld\n" , res);
return 0;
}
F 猫猫与宝石
对于前\(m\)项中的任意一项\(i\),产生的贡献是\(\frac 1 2 a_i\times E(c)\),然后我们考虑\(E(c)\)的值,先说\(E(c)\)要产生贡献的前提条件是什么?就是一定要选\(a_i\),除此之外的\(m-1\)项按照期望计算就是会选出\(\frac{m-1}{2}\)所以\(E(c)=\frac{m-1}2 + 1\)。
所以前\(m\)项的答案就是\(\sum_{i=1}^{m} \frac 1 2 a_i (\frac{m-1} 2 + 1)=\frac{m+1}{4}\sum a_i\)
所以计算前缀和的时候就可以计算出答案。
#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;
}
const int mod = 998244353 , inv4 = 748683265;
int32_t main() {
int n = read() , sum = 0;
for( int i = 1 ; i <= n ; i ++ ){
sum = ( sum + read() ) % mod;
printf("%lld " , sum * (i+1) % mod * inv4 % mod );
}
return 0;
}