Codeforces Round 1049 (Div. 2)
A. Shift Sort
发现左移或右移等价于交换两个位置的数
所以答案即为前 \(cnt0\) 个数中有几个 \(1\)
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;
void solve(){
int n;
cin>>n;
vector<int> a(n+1);
int cnt=0;
for(int i=1;i<=n;i++){
char ch;
cin>>ch;
a[i]=(ch=='1');
if(a[i]==0) cnt++;
}
int ans=0;
for(int i=1;i<=cnt;i++){
if(a[i]) ans++;
}
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int ct=1;
cin>>ct;
while(ct--){
solve();
}
return 0;
}
B. Another Divisibility Problem
\(y=2*x\)
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;
void solve(){
int n;
cin>>n;
cout<<2*n<<endl;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int ct=1;
cin>>ct;
while(ct--){
solve();
}
return 0;
}
C. Ultimate Value
后手一定直接结束游戏
所以只需要计算第一次先手能得到的最大贡献
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;
void solve(){
int n;
cin>>n;
vector<int> a(n+1);
int sum=0;
for(int i=1;i<=n;i++){
cin>>a[i];
if(i&1) sum+=a[i];
else sum-=a[i];
}
int t=0;
//l,r奇偶性相同
if(n&1) t=n-1;
else t=n-2;
vector<int> l(n+1),preoddl(n+1,-inf),preevenl(n+1,-inf);
for(int i=1;i<=n;i++){
if(i&1) l[i]=-i-2*a[i];
else l[i]=-i+2*a[i];
preoddl[i]=preoddl[i-1];
preevenl[i]=preevenl[i-1];
if(i&1) preoddl[i]=max(preoddl[i],l[i]);
else preevenl[i]=max(preevenl[i],l[i]);
}
for(int i=2;i<=n;i++){
if(i&1){
t=max(t,preevenl[i-1]+i-2*a[i]);
// cout<<preevenl[i-1]<<" "<<i-2*a[i]<<" ";
}
else{
t=max(t,preoddl[i-1]+i+2*a[i]);
// if(i==6) cout<<preoddl[i-1]<<" "<<i-2*a[i]<<" ";
}
}
// cout<<endl;
cout<<sum+t<<endl;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int ct=1;
cin>>ct;
while(ct--){
solve();
}
return 0;
}
D. A Cruel Segment's Thesis
\(n\) 是偶数时,可以直接两两配对计算出答案
此时需要 \(n/2\) 个 \(-y\),和 \(n/2\) 个 \(r\)
如果 \(n\) 是奇数,则需要在偶数的基础上,枚举单独拎出来哪一个线段,对答案的副贡献最小
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 998244353;
void solve(){
int n;
cin>>n;
vector<int> r(n+1),l(n+1);
vector<pii> a(n+1);
int ans=0;
for(int i=1;i<=n;i++){
cin>>l[i]>>r[i];
ans+=(r[i]-l[i]);
ans+=r[i];
a[i]={r[i]+l[i],r[i]};
}
vector<int> st(n+1);//st[i]:i是否给L贡献
sort(a.begin()+1,a.end());
for(int i=1;i<=n/2;i++){
ans-=a[i].first;
st[i]=1;
}
if(n&1){
//如果单独的段,在之前贡献的是r,则只需要把这个r删掉即可
int cost=inf;
for(int i=n/2+1;i<=n;i++){
cost=min(cost,a[i].second);
}
//如果单独的段,之前贡献的是l,则需要加上这个l
//再从贡献r的里面找一个改为贡献l,cost是-r-l
for(int i=1;i<=n/2;i++){
cost=min(cost,(-a[i].first+a[i].second)+a[n/2+1].first);
}
cout<<ans-cost<<endl;
}
else{//偶数
cout<<ans<<endl;
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int ct=1;
cin>>ct;
while(ct--){
solve();
}
return 0;
}
E1. Prime Gaming (Easy Version)
设状态 \(dp[i] [j] [k]\) 表示,当前轮到玩家 \(i\),还剩 \(j\) 堆石子,石子的状态是 \(k\)
\(i:(0/1)\),\(k:\) 如果第 \(x\) 堆有一个石子,则 \(k\) 的第 \(x\) 位为 \(0\),否则为 \(1\)
\(dp[i] [j] [k]\) 可以从 \(dp[-] [j-1] [-]\) 转移得到
点击查看代码
#include<bits/stdc++.h>
// #define int long long
using namespace std;
using pii=pair<int,int>;
using ll = long long;
using ull = unsigned long long;
const ll inf = 1e18;
const int mod = 1e9+7;
/*支持define int long long 的自动取模类*/
template<const int T>
struct ModInt {
const static int mod = T;
int x;
ModInt(signed x = 0) : x(x % mod) {}
ModInt(long long x) : x((int)x % mod) {}
int val() { return x; }
ModInt operator + (const ModInt &a) const { int x0 = x + a.x; return ModInt(x0 < mod ? x0 : x0 - mod); }
ModInt operator - (const ModInt &a) const { int x0 = x - a.x; return ModInt(x0 < 0 ? x0 + mod : x0); }
ModInt operator * (const ModInt &a) const { return ModInt(1LL * x * a.x % mod); }
ModInt operator / (const ModInt &a) const { return *this * a.inv(); }
bool operator == (const ModInt &a) const { return x == a.x; };
bool operator != (const ModInt &a) const { return x != a.x; };
void operator += (const ModInt &a) { x += a.x; if (x >= mod) x -= mod; }
void operator -= (const ModInt &a) { x -= a.x; if (x < 0) x += mod; }
void operator *= (const ModInt &a) { x = 1LL * x * a.x % mod; }
void operator /= (const ModInt &a) { *this = *this / a; }
friend ModInt operator + (int y, const ModInt &a){ int x0 = y + a.x; return ModInt(x0 < mod ? x0 : x0 - mod); }
friend ModInt operator - (int y, const ModInt &a){ int x0 = y - a.x; return ModInt(x0 < 0 ? x0 + mod : x0); }
friend ModInt operator * (int y, const ModInt &a){ return ModInt(1LL * y * a.x % mod);}
friend ModInt operator / (int y, const ModInt &a){ return ModInt(y) / a;}
friend ostream &operator<<(ostream &os, const ModInt &a) { return os << a.x;}
friend istream &operator>>(istream &is, ModInt &t){return is >> t.x;}
ModInt pow(int64_t n) const {
ModInt res(1), mul(x);
while(n){
if (n & 1) res *= mul;
mul *= mul;
n >>= 1;
}
return res;
}
ModInt inv() const {
int a = x, b = mod, u = 1, v = 0;
while (b) {
int t = a / b;
a -= t * b; swap(a, b);
u -= t * v; swap(u, v);
}
if (u < 0) u += mod;
return u;
}
};
using mint = ModInt<mod>;
void solve(){
int n,m,k;
cin>>n>>m>>k;
vector<int> good(k);
for(int i=0;i<k;i++){
cin>>good[i];
}
if(m==1){
cout<<1<<endl;
return;
}
//f[i][j][k]
//i:0-ALice/1-Bob
//轮到i操作时,还剩j个数,状态为k的答案
vector<vector<vector<int>>> f(2,vector<vector<int>>(n+1,vector<int>(1<<n)));
//状态mask移除第k位后的结果
auto get=[&](int mask,int pos)->int {
int up=mask>>(pos+1);
int low=mask&((1<<pos)-1);
return (up<<pos)+low;
};
//还有多少位数
for(int i=1;i<=n;i++){
if(i==1){
f[0][i][1]=1;
f[0][i][0]=0;
f[1][i][1]=1;
f[1][i][0]=0;
}
else{
for(int k=0;k<(1<<i);k++){
int ansA=0;//只要可以转移到一个1,ansA就是1
int ansB=1;//只要可以转移到一个0,ansB就是0
for(auto pos:good){
if(pos>i) continue;
int mask=get(k,pos-1);
ansA|=f[1][i-1][mask];
ansB&=f[0][i-1][mask];
}
f[0][i][k]=ansA;
f[1][i][k]=ansB;
}
}
}
mint ans=0;
for(int i=0;i<(1<<n);i++){
ans+=(f[0][n][i]+1);
}
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int ct=1;
cin>>ct;
while(ct--){
solve();
}
return 0;
}

浙公网安备 33010602011771号