CF1342
Road To Zero
显然我们要判断 \(2\times a\) 和 \(b\) 的关系。
如果 \(2\times a\le b\),那么我们都选 \(a\) 操作是绝对不劣的,输出 \(x+y\)。
否则我们先用 \(b\) 操作将某一个数减到 \(0\),再用另一个操作来处理第二个数。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define getchar() cin.get()
#define pii pair<int,int>
#define fi first
#define se second
#define int long long
const int N = 1e3 + 5;
const int mod = 998244353;
int read()
{
int f = 1 , x = 0;
char ch = getchar();
while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
return x * f;
}
signed main ()
{
ios::sync_with_stdio(false);
cin.tie(0) , cout.tie(0);
int T = read();
while ( T -- )
{
int x = read() , y = read() , a = read() , b = read();
if ( 2 * a <= b ) cout << ( x + y ) * a << endl;
else cout << abs ( x - y ) * a + min ( x , y ) * b << endl;
}
return 0;
}
Binary Period
显然任何串都是 \(2\times t\) 长度的 \(01\) 相间的串的子串,那么最大周期保证了不超过 \(2\)。
那么只需要特判全为 \(0\) 或者全为 \(1\) 的情况即可。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define getchar() cin.get()
#define pii pair<int,int>
#define fi first
#define se second
#define int long long
const int N = 1e3 + 5;
const int mod = 998244353;
int read()
{
int f = 1 , x = 0;
char ch = getchar();
while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
return x * f;
}
int n , is0 , is1;
string s;
signed main ()
{
ios::sync_with_stdio(false);
cin.tie(0) , cout.tie(0);
int T = read();
while ( T -- )
{
is0 = 0 , is1 = 0;
cin >> s;
for ( int i = 0 ; i < s.size() ; i ++ ) s[i] == '0' ? is0 = 1 : is1 = 1;
if ( is0 + is1 == 1 ) { cout << s << endl; continue; }
for ( int i = 0 ; i < s.size() ; i ++ )
cout << 0 << 1;
cout << endl;
}
return 0;
}
Yet Another Counting Problem
可以看出循环节为 \(ab\),那么我们对于每一组数据,预处理 \(\operatorname{lcm}(a,b)\) 之间的答案存在数组 \(sum\) 中,用前缀和查询即可。
这里注意答案的组成:将对于 \(x\) 的一次查询分成整段和散段,整段贡献为 \(\frac {x} {\operatorname{lcm}(a,b)}\times sum[\operatorname{lcm}(a,b)]\),对于散段,计入答案即为 \(sum[x\bmod \operatorname{lcm}(a,b)]\)。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define getchar() cin.get()
#define pii pair<int,int>
#define fi first
#define se second
#define int long long
const int N = 1e5 + 5;
int read()
{
int f = 1 , x = 0;
char ch = getchar();
while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
return x * f;
}
int a , b , q , sum[N] , lim;
int query ( int x ) { return sum[x%lim] + sum[lim] * ( x / lim ); }
signed main ()
{
ios::sync_with_stdio(false);
cin.tie(0) , cout.tie(0);
int T = read();
while ( T -- )
{
a = read() , b = read() , q = read();
lim = a * b / __gcd ( a , b );
for ( int i = 1 ; i <= lim ; i ++ ) sum[i] = sum[i-1] + ( i % a % b != i % b % a );
for ( int i = 1 ; i <= q ; i ++ )
{
int l = read() , r = read();
cout << query(r) - query(l-1) << ' ';
}
cout << endl;
}
return 0;
}
Multiple Testcases
题面没看懂。
大意是让你不重不漏地平均分配一个数组 \(a\) 到 \(m\) 个容器中,使得对于每一个容器,每一个数 \(i\in[1,k]\),都满足 \(\ge i\) 的 \(a\) 数量 \(\le c_i\)。
首先对于 \(a\) 进行桶的标记,并从 \(k\) 到 \(1\) 做一个后缀和,算出每一个 \(i\in[1,k]\) 的最小分配数,取最大值输出。
对于方案的输出,一定是将 \(a\) 数组从小到大,均分到每一个容器中,这样才能保证我们满足条件的分配数尽量少。
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define inl inline
#define eb emplace_back
#define getchar() cin.get()
#define pii pair<int,int>
#define fi first
#define se second
#define int long long
const int N = 2e5 + 5;
int read()
{
int f = 1 , x = 0;
char ch = getchar();
while ( !isdigit(ch) ) { if ( ch == '-' ) f = -1; ch = getchar(); }
while ( isdigit(ch) ) { x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ); ch = getchar(); }
return x * f;
}
int n , k , sum[N] , a[N] , ans , c[N];
signed main ()
{
ios::sync_with_stdio(false);
cin.tie(0) , cout.tie(0);
n = read() , k = read();
for ( int i = 1 ; i <= n ; i ++ ) a[i] = read() , sum[a[i]] ++;
for ( int i = k ; i ; i -- ) sum[i] += sum[i+1];
for ( int i = 1 ; i <= k ; i ++ ) c[i] = read();
for ( int i = 1 ; i <= k ; i ++ ) ans = max ( ans , sum[i] / c[i] + !! ( sum[i] % c[i] ) );
cout << ans << endl;
sort ( a + 1 , a + n + 1 );
for ( int i = 1 ; i <= ans ; i ++ )
{
int stp = i , cnt = 0;
while ( stp <= n ) ++ cnt , stp += ans;
cout << cnt << ' ';
stp = i;
while ( stp <= n ) cout << a[stp] << ' ' , stp += ans;;
cout << endl;
}
return 0;
}