Educational Codeforces Round 34
A. Hungry Student Problem
枚举一个就完事了
view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define scs(x) scanf("%s",s)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;
void solve(){
int x;
sci(x);
for(int a = 0; a <= x / 3; a++){
int l = x - a * 3;
if(l%7==0){
cout << "YES" << endl;
return;
}
}
cout << "NO" << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
int n; sci(n);
while(n--) solve();
return 0;
}
B. The Modcrab
二分用药次数,必然先嗑完药再打
view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define scs(x) scanf("%s",s)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;
void solve(){
int h1, a1, c1, h2, a2;
sci(h1); sci(a1); sci(c1); sci(h2); sci(a2);
auto check = [&](int m){
int h = h1 + (c1 - a2) * m;
int s1 = h2 / a1 + (h2 % a1 != 0 ? 1 : 0);
int s2 = h / a2 + (h % a2 != 0 ? 1 : 0);
return s1 <= s2;
};
int l = 0, r = 1e5+7;
while(l<=r){
int mid = (l + r) >> 1;
if(check(mid)) r = mid - 1;
else l = mid + 1;
}
int cnt = h2 / a1 + (h2 % a1 != 0 ? 1 : 0);
cout << cnt + l << endl;
for(int i = 1; i <= l; i++) cout << "HEAL" << endl;
for(int i = 1; i <= cnt; i++) cout << "STRIKE" << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
C. Boxes Packing
排个序然后用个优先队列维护每个单调序列的最大值,每次选最小的然后把当前值作为单调序列的最大值
view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define scs(x) scanf("%s",s)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;
void solve(){
int n; sci(n);
vi A(n); for(int &x : A) sci(x);
sort(all(A));
priority_queue<int, vi, greater<int> > que;
for(int x : A){
if(que.empty() or que.top()>=x) que.push(0);
auto p = que.top();
que.pop();
que.push(x);
}
cout << que.size() << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
D. Almost Difference
先算所有的\(y-x\)的和,然后把差值为\(1\)的单独算一下
会爆\(long\ long\),用了\(\_\_int\_128t\)
view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define scs(x) scanf("%s",s)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;
void print(__int128 x){
if(x < 0){
x = -x;
putchar('-');
}
if(x > 9) print(x/10);
putchar(x%10 + '0');
}
void solve(){
int n; sci(n);
vi A(n); for(int &x : A) sci(x);
__int128_t ret = 0;
for(LL i = 0, s = 0; i < n; s += A[i], i++) ret += i * A[i] - s;
int p1 = 0, n1 = 0;
map<int,int> msk;
for(int i = 0; i < n; i++){
p1 += msk[A[i]-1];
n1 += msk[A[i]+1];
msk[A[i]]++;
}
ret -= p1; ret += n1;
print(ret);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
E. Swapping Characters
如果全部都一样,就随便换两个位置就好了
否则找两个不一样的,找到这些不一样的位置,分别枚举两个串的不同位置和其他位置交换得到的串,和所有串匹配一下判断是否符合条件即可
view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define scs(s) scanf("%s",s)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 5e3+7;
int k, n;
string s[MAXN];
void solve(){
____();
cin >> k >> n;
for(int i = 0; i < k; i++) cin >> s[i];
sort(s,s+k);
k = unique(s,s+k) - s;
auto check = [&](string &str, int id){
bool same = false;
set<char> S;
for(char c : str){
if(S.count(c)){
same = true;
break;
}
S.insert(c);
}
vi A(26);
for(char x : str) A[x-'a']++;
for(int i = 0; i < k; i++){
if(i==id) continue;
int dif = 0;
for(int j = 0; j < n; j++) if(s[id][j]!=s[i][j]) dif++;
vi B(26);
for(char x : s[i]) B[x-'a']++;
for(int j = 0; j < 26; j++) if(A[j]!=B[j]) return false;
if(dif==2 or (dif==0 and same)) continue;
return false;
}
return true;
};
for(int i = 0; i < k; i++) for(int j = i + 1; j < k; j++){
if(s[i]==s[j]) continue;
vi pos;
for(int x = 0; x < n; x++) if(s[i][x]!=s[j][x]) pos << x;
if(pos.size()==1 or pos.size()>4){
cout << -1 << endl;
return;
}
for(int p1 : pos){
for(int x = 0; x < n; x++){
if(x==p1) continue;
bool ok = true;
swap(s[i][p1],s[i][x]);
if(check(s[i],i)){
cout << s[i] << endl;
return;
}
swap(s[i][p1],s[i][x]);
}
}
for(int p1 : pos){
for(int x = 0; x < n; x++){
if(x==p1) continue;
bool ok = true;
swap(s[j][p1],s[j][x]);
if(check(s[j],j)){
cout << s[j] << endl;
return;
}
swap(s[j][p1],s[j][x]);
}
}
}
if(k==1) swap(s[0][0],s[0][1]), cout << s[0] << endl;
else cout << -1 << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
F. Clear The Matrix
最大的正方形只有\(4\),考虑\(DP\),对于每一列,其实只和它前面的三列有关系,那么可以用\(12\)位二进制来存前三列的状态,\(dp[i][msk]\)表示第\(i\)列之前已经完全清除且从第\(i\)列开始的三列的状态是\(msk\)的最小花费,通过枚举四种正方形和填在最左边列的位置进行转移
为了方便可以多加四行
view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define scs(s) scanf("%s",s)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 1e3+7;
int n, c[4], sta[MAXN], clr[4];
char s[4][MAXN];
int clear(int msk, int sz, int pos){ return msk & (((1 << 12) - 1) ^ (clr[sz-1] << pos)); }
void solve(){
clr[0] = 1 << 8;
clr[1] = (3 << 4) | (3 << 8);
clr[2] = 7 | (7 << 4) | (7 << 8);
sci(n);
for(int i = 0; i < 4; i++) sci(c[i]);
for(int i = 0; i < 4; i++) scs(s[i]);
for(int t = 0; t < 4; t++) for(int i = 0; i < 4; i++) s[i][n+t] = '.';
for(int i = 0; i < n + 4; i++) for(int j = 0; j < 4; j++) if(s[j][i]=='*') sta[i] |= (1 << j);
vi f(1<<12,INF);
int initsta = (sta[0] << 8) | (sta[1] << 4) | sta[2];
f[initsta] = 0;
for(int i = 0; i <= n; i++){
vi next_f(1<<12,INF);
for(int msk = (1 << 8); msk < (1 << 12); msk++) cmin(next_f[0],f[msk]+c[3]);
for(int msk = (1 << 12) - 1; ~msk; msk--){
if(f[msk]==INF) continue;
for(int pos = 0; pos < 4; pos++) for(int sz = 1; pos + sz <= 4; sz++){
if(sz==4) continue;
cmin(f[clear(msk,sz,pos)],f[msk]+c[sz-1]);
}
}
for(int msk = 0; msk < (1 << 8); msk++) cmin(next_f[(msk<<4)|sta[i+3]],f[msk]);
f.swap(next_f);
}
cout << f[0] << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
G. Yet Another Maxflow Problem
首先把最大流问题转化为最小割问题,那么可以发现左右两部分最多只会割掉一条边,假设左边割的边是\(x\rightarrow x+1\),右边割的是\(y\rightarrow y+1\),那么中间的边\(i\rightarrow j\)(其中\(i\)为左半部分的点\(j\)为右半部分的点且\(i\le x,j\ge y+1\))都是要割的
由于只有左半部分不是固定的,我们先考虑对于左半部分的每条割边,右半部分和中间连边的最小割,这个可以用线段树来动态维护,考虑从上到下枚举左半部分的割边,然后把对应的连着两部分的边的贡献加到线段树里面去,由于对于割边\(y\rightarrow y+1\),只有\(i\rightarrow j,j\ge y+1\)的边才是有用的,那么我们要求的其实就是一个后缀和的最大值,要求单点修改区间后缀最值查询,我们可以变成前缀修改,区间最值查询
现在对于每条左边的割边,右边割边的最值确定了,那么只要动态维护左边的最值就好了
view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define scs(s) scanf("%s",s)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;
vi ca, cb;
vector<pii> G[MAXN];
struct SegmentTree{
LL minn[MAXN<<2], lazy[MAXN<<2];
int l[MAXN<<2], r[MAXN<<2];
#define ls(rt) rt << 1
#define rs(rt) rt << 1 | 1
#define pushup(rt) minn[rt] = min(minn[ls(rt)],minn[rs(rt)])
void pushdown(int rt){
if(!lazy[rt]) return;
lazy[ls(rt)] += lazy[rt]; lazy[rs(rt)] += lazy[rt];
minn[ls(rt)] += lazy[rt]; minn[rs(rt)] += lazy[rt];
lazy[rt] = 0;
}
void build(int L, int R, int rt = 1){
l[rt] = L; r[rt] = R;
if(L + 1 == R) return;
int mid = (L + R) >> 1;
build(L,mid,ls(rt)); build(mid,R,rs(rt));
}
void modify(int L, int R, LL x, int rt = 1){
if(L>=r[rt] or l[rt]>=R) return;
if(L<=l[rt] and r[rt]<=R){
lazy[rt] += x; minn[rt] += x;
return;
}
pushdown(rt);
modify(L,R,x,ls(rt)); modify(L,R,x,rs(rt));
pushup(rt);
}
LL qmin(int L, int R, int rt = 1){
if(L>=r[rt] or l[rt]>=R) return INF;
if(L<=l[rt] and r[rt]<=R) return minn[rt];
pushdown(rt);
return min(qmin(L,R,ls(rt)),qmin(L,R,rs(rt)));
}
}STa,STb;
void solve(){
int n, m, q;
sci(n); sci(m); sci(q);
ca.resize(n+1); cb.resize(n+1);
for(int i = 1; i < n; i++) sci(ca[i]), sci(cb[i]);
STa.build(1,n+1);
STb.build(1,n+1);
for(int i = 1; i <= n; i++) STa.modify(i,i+1,cb[i-1]);
for(int i = 1; i <= m; i++){
int u, v, w;
sci(u); sci(v); sci(w);
G[u] << make_pair(v,w);
}
for(int i = 1; i <= n; i++){
for(auto p : G[i]) STa.modify(1,p.first+1,p.second);
STb.modify(i,i+1,STa.qmin(1,n+1)+ca[i]);
}
cout << STb.qmin(1,n+1) << endl;
while(q--){
int x, w;
sci(x); sci(w);
STb.modify(x,x+1,w-ca[x]);
ca[x] = w;
cout << STb.qmin(1,n+1) << endl;
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}