Educational Codeforces Round 29
A. Quasi-palindrome
把后缀\(0\)去掉之后看一下串翻转之后和原串是否相同即可
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 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(){
string s;
cin >> s;
while(!s.empty() and s.back()=='0') s.pop_back();
if(s.empty()) cout << "YES" << endl;
else{
string t = s;
reverse(all(t));
if(t==s) cout << "YES" << endl;
else cout << "NO" << endl;
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
B. Kayaking
枚举删掉的两个,剩下的排序贪心选即可
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 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<<1); for(int &x : A) sci(x);
int ret = INT_MAX;
for(int i = 1; i < (n << 1); i++) for(int j = 0; j < i; j++){
vi vec;
for(int k = 0; k < (int)A.size(); k++) if(k!=i and k!=j) vec << A[k];
sort(all(vec));
int tot = 0;
for(int i = 1; i < (int)vec.size(); i+=2) tot += vec[i] - vec[i-1];
cmin(ret,tot);
}
cout << ret << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
C. 1-2-3
找循环节即可
可能先是一条链,再是循环
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 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;
int A[4][4], B[4][4];
int check(int x, int y){
if(x==3){
if(y==3) return 0;
else if(y==2) return 1;
else return -1;
}else if(x==2){
if(y==2) return 0;
else if(y==1) return 1;
else return -1;
}else if(x==1){
if(y==1) return 0;
else if(y==3) return 1;
else if(y==2) return -1;
}
}
void solve(){
LL k; int a, b;
scl(k); sci(a); sci(b);
for(int i = 1; i <= 3; i++) for(int j = 1; j <= 3; j++) sci(A[i][j]);
for(int i = 1; i <= 3; i++) for(int j = 1; j <= 3; j++) sci(B[i][j]);
map<pair<int,int>, bool> msk;
vector<pair<int,int> > vec;
vec << make_pair(a,b);
msk[{a,b}] = true;
while(true){
int nexta = A[a][b], nextb = B[a][b];
a = nexta, b = nextb;
if(msk.count({a,b})) break;
msk[{a,b}] = true;
vec << make_pair(a,b);
}
vector<pair<int,int> > loop;
int stpos = 0;
for(int i = 0; ;i++) if(vec[i]==make_pair(a,b)){
stpos = i;
break;
}
for(int i = stpos; i < (int)vec.size(); i++) loop << vec[i];
vector<pair<int,int> > v1, v2;
for(int i = 0; i < (int)vec.size(); i++) {
pii pre = i==0?make_pair(0,0):v1.back();
int x = vec[i].first, y = vec[i].second;
if(check(x,y)==1) v1 << make_pair(pre.first+1,pre.second);
else if(check(x,y)==0) v1 << pre;
else v1 << make_pair(pre.first,pre.second+1);
}
for(int i = 0; i < (int)loop.size(); i++){
pii pre = i==0?make_pair(0,0):v2.back();
int x = loop[i].first, y = loop[i].second;
if(check(x,y)==1) v2 << make_pair(pre.first+1,pre.second);
else if(check(x,y)==0) v2 << pre;
else v2 << make_pair(pre.first,pre.second+1);
}
if(k<=vec.size()) cout << v1[k-1].first << ' ' << v1[k-1].second << endl;
else{
k -= vec.size();
LL loops = k / loop.size();
LL lft = k % loop.size();
pll P = v1.back();
P.first += loops * v2.back().first;
P.second += loops * v2.back().second;
if(lft){
P.first += v2[lft-1].first;
P.second += v2[lft-1].second;
}
cout << P.first << ' ' << P.second << endl;
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
D. Yet Another Array Queries Problem
对每个位置单独操作,反向找初始位置即可
复杂度\(O(m\cdot q)\)
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 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;
int n, q, m;
void solve(){
sci(n); sci(q); sci(m);
vi A(n); for(int &x : A) sci(x);
vector<pair<int,pii> > Q(q);
for(auto &p : Q){
sci(p.first), sci(p.second.first), sci(p.second.second);
p.second.first--; p.second.second--;
}
reverse(all(Q));
for(int i = 0; i < m; i++){
int idx; sci(idx); idx--;
for(auto &p : Q){
int tp = p.first, l = p.second.first, r = p.second.second;
if(idx<l or idx>r) continue;
if(tp==1) idx = (idx==l ? r : idx-1);
else idx = r - idx + l;
}
cout << A[idx] << ' ';
}
cout << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
E. Turn Off The TV
把坐标离散化,然后对每条线段覆盖的区间进行区间加\(1\)
用差分前缀和来做,然后把每个位置的覆盖次数算出来,如果大于等于\(2\)赋值\(1\),否则赋值\(0\)
枚举每条线段,判断这条线段覆盖的点是否都有超过两条线段覆盖即可
注意离散化的时候还要加入线段端点的左右端点,否则会有遗漏点没被考虑到
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 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);
vector<pii> A(n); for(auto &p : A) sci(p.first), sci(p.second);
vector<int> vec;
for(auto &p : A) vec << p.first << p.second;
sort(all(vec)); vec.erase(unique(all(vec)),vec.end());
for(int i = 0, sz = vec.size(); i < sz; i++){
vec << vec[i] - 1;
vec << vec[i] + 1;
}
sort(all(vec)); vec.erase(unique(all(vec)),vec.end());
for(auto &p : A){
p.first = lower_bound(all(vec),p.first) - vec.begin() + 1;
p.second = lower_bound(all(vec),p.second) - vec.begin() + 1;
}
vi presum(vec.size() << 1, 0);
for(auto &p : A){
presum[p.first]++;
presum[p.second+1]--;
}
for(int i = 1; i < (int)presum.size(); i++) presum[i] += presum[i-1];
for(auto &x : presum) x = (x>=2 ? 1 : 0);
for(int i = 1; i < (int)presum.size(); i++) presum[i] += presum[i-1];
for(int i = 0; i < (int)A.size(); i++){
int l = A[i].first, r = A[i].second;
if(presum[r] - presum[l-1] == r - l + 1){
cout << i + 1 << endl;
return;
}
}
cout << -1 << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}
F. Almost Permutation
先暴力把每个数可以在的区间找出来
然后费用流建图
可以发现每多出现一次同一个数,费用会额外加上\(c^2-(c-1)^2 = 2 \cdot c - 1\)
每个数字向汇点连\(n\)条边,每条边容量\(1\),费用分别为\(2\cdot c - 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 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 = 111;
int n, q, low[MAXN], high[MAXN];
int pre[MAXN], preid[MAXN], dist[MAXN], flow[MAXN];
bool vis[MAXN];
#define S 0
#define T MAXN - 1
struct EDGE{
int to,cap,fee,rev;
EDGE(){}
EDGE(int _to, int _cap, int _fee, int _rev){
to = _to; cap = _cap;
fee = _fee; rev = _rev;
}
};
vector<EDGE> G[MAXN];
void ADDEDGE(int u, int v, int cap, int fee){
G[u].emplace_back(EDGE(v,cap,fee,(int)G[v].size()));
G[v].emplace_back(EDGE(u,0,-fee,(int)G[u].size()-1));
}
bool spfa(){
memset(dist,0x3f,sizeof(dist));
dist[S] = 0;
flow[S] = INF;
memset(vis,0,sizeof(vis));
queue<int> que;
que.push(S);
while(!que.empty()){
int u = que.front();
que.pop();
vis[u] = 0;
for(int i = 0; i < (int)G[u].size(); i++){
auto e = G[u][i];
if(!e.cap or dist[e.to]<=dist[u]+e.fee) continue;
dist[e.to] = dist[u] + e.fee;
flow[e.to] = min(e.cap,flow[u]);
pre[e.to] = u; preid[e.to] = i;
if(!vis[e.to]){
vis[e.to] = 1;
que.push(e.to);
}
}
}
return dist[T]!=INF;
}
int mcmf(){
int cost = 0;
while(spfa()){
int u = T;
cost += dist[T] * flow[T];
while(u!=S){
int p = pre[u], id = preid[u];
G[p][id].cap -= flow[T];
G[u][G[p][id].rev].cap += flow[T];
u = pre[u];
}
}
return cost;
}
void solve(){
sci(n); sci(q);
for(int i = 1; i <= n; i++) low[i] = 1, high[i] = n;
for(int i = 1; i <= q; i++){
int tp, l, r, v;
sci(tp); sci(l); sci(r); sci(v);
if(tp==1) for(int j = l; j <= r; j++) cmax(low[j],v);
else for(int j = l; j <= r; j++) cmin(high[j],v);
}
for(int i = 1; i <= n; i++) if(low[i]>high[i]){
cout << -1 << endl;
return;
}
for(int i = 1; i <= n; i++){
ADDEDGE(S,i,1,0);
for(int j = low[i]; j <= high[i]; j++) ADDEDGE(i,j+n,1,0);
for(int j = 1; j <= n; j++) ADDEDGE(i+n,T,1,2*j-1);
}
cout << mcmf() << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}