B - RGB Coloring
题意:一共n(1e5)个位置,可以填A,B,A+B三种数字,使得最后总和为k(1e10)
思路:ax+by==k 对于A+B的情况,其实就是把A,B随机放,可以重叠。那么O(n)枚举x,找到y。ans+=c(n,x)*c(n,y);
#include<bits/stdc++.h>
#define PI acos(-1.0)
#define pb push_back
#define F first
#define S second
#define debug puts
#define setp cout << fixed << setprecision(15)
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long ll;
const int N=3e5+5;
const int MOD=998244353;
ll F[N], Finv[N], inv[N];//F是阶乘,Finv是逆元的阶乘
void init(){
inv[1] = 1;
for(int i = 2; i < N; i ++){
inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD;
}
F[0] = Finv[0] = 1;
for(int i = 1; i < N; i ++){
F[i] = F[i-1] * 1ll * i % MOD;
Finv[i] = Finv[i-1] * 1ll * inv[i] % MOD;
}
}
ll c(int n, int m){//comb(n, m)就是C(n, m)
if(m < 0 || m > n) return 0;
return F[n] * 1ll * Finv[n - m] % MOD * Finv[m] % MOD;
}
int main(void){
FAST_IO;
init();
ll n,a,b,k;
cin >>n>>a>>b>>k;
/// ax+by==k; x(0,n);
ll ans=0;
for(int x=0;x<=n;x++){
if((k-a*x)%b==0){
ll y=(k-a*x)/b;
// cout << "~"<<c(n,x)<<endl;
// cout << "~"<<c(n,y)<<endl;
ans=(ans+c(n,x)%MOD*c(n,y))%MOD;
}
}
cout << ans<< endl;
return 0;
}
C - Interval Game
题意:2个人博弈。 一维坐标上,A起初在0,最终也要回到0点。 B告诉A一个区间[L,R],A要步入这个区间。A希望走的路程尽可能小,B希望A走的路程尽可能的大。
思路:肯定先让他走到最右边,再扔回最左边。 画几个样例模拟一下,应该可以发现计算规律
#include<bits/stdc++.h>
#define PI acos(-1.0)
#define pb push_back
#define F first
#define S second
#define debug puts
#define setp cout << fixed << setprecision(15)
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long ll;
const int N=3e5+5;
const int MOD=998244353;
int main(void){
FAST_IO;
int n;
cin >> n;
vector<int> l(n+1),r(n+1);
// cout << a[0]<<endl;
for(int i=1;i<=n;i++){
int a,b;
cin >> a >>b;
l[i]=a,r[i]=b;
}
sort(l.rbegin(),l.rend());
sort(r.begin(),r.end());
ll ans=0;
for(int i=0;i<=n;i++){
if(l[i]>r[i]){
ans+=2*(l[i]-r[i]);
}
}
cout << ans << endl;
return 0;
}