Educational Codeforces Round 27

Educational Codeforces Round 27  

A. Chess Tourney

拿第一队最弱的和第二队最强的比就好了

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(2*n); for(int &x : A) sci(x);
    sort(all(A));
    if(A[n]>A[n-1]) 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.Luba And The Ticket

每次拿变化可以最大的数字去变

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;
char s[10];
void solve(){
    cin >> s;
    int s1 = 0, s2 = 0;
    for(int i = 0; i < 3; i++) s1 += s[i] - '0', s2 += s[i+3] - '0';
    int ret = 0;
    while(s1!=s2){
        if(s1<s2){
            int a = 0, b = 3;
            if(s[1]<s[0]) a = 1;
            if(s[2]<s[a]) a = 2;
            if(s[4]>s[3]) b = 4;
            if(s[5]>s[b]) b = 5;
            if('9'-s[a] > s[b]-'0'){
                if(s2-s1<='9'-s[a]){
                    ret++;
                    break;
                }else{
                    s1 += '9' - s[a];
                    s[a] = '9';
                    ret++;
                }
            }else{
                if(s2-s1<=s[b]-'0'){
                    ret++;
                    break;
                }else{
                    s2 -= s[b] - '0';
                    s[b] = '0';
                    ret++;
                }
            }
        }else{
            swap(s1,s2);
            for(int i = 0; i < 3; i++) swap(s[i],s[i+3]);
        }
    }
    cout << ret << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

C. Two TVs

维护两个指针,分别表示当前看完的结束时间,把所有区间按左端点排序,遇到看不了的电视就输出\(NO\)

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;

void solve(){
    sci(n);
    vector<pii> A(n);
    for(auto &p : A) sci(p.first), sci(p.second);
    sort(all(A));
    int a = -1, b = -1;
    for(auto p : A){
        if(p.first > a) a = p.second;
        else if(p.first > b) b = p.second;
        else{
            cout << "NO" << endl;
            return;
        }
    }
    cout << "YES" << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

D. Driving Test

用栈存限速,记一下过了多少个的不能超车,加速了之后从栈顶把超速的都删掉,加上删掉的数量

超车了就加上全部的记下的标记

遇到可超车就把标记全部删掉

模拟即可

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);
    int cnt = 0;
    int noovertake = 0;
    stack<int> speedlimit;
    int carspeed = 0;
    while(n--){
        int tp; sci(tp);
        if(tp==1){
            sci(carspeed);
            while(!speedlimit.empty() and speedlimit.top()<carspeed) cnt++, speedlimit.pop();
        }else if(tp==2){
            cnt += noovertake;
            noovertake = 0;
        }else if(tp==3){
            int x; sci(x);
            if(carspeed>x) cnt++;
            else speedlimit.push(x);
        }else if(tp==4) noovertake = 0;
        else if(tp==5) while(!speedlimit.empty()) speedlimit.pop();
        else noovertake++;
    }
    cout << cnt << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

E. Fire in the City

二分时间

关于\(check\),可以用离散化然后扫描线来做,具体就是找到没有被覆盖的点的\(x\)最大最小值和\(y\)的最大最小值

然后判断能否用一个边长为\(mid*2+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 = 5e4+7;
int n, m, k;
vector<pii> vec;

struct SegTree{
    int cover[MAXN<<2], l[MAXN<<2], r[MAXN<<2];
    bool ept[MAXN<<2];
    #define ls(rt) rt << 1
    #define rs(rt) rt << 1 | 1
    void pushup(int rt){
        if(cover[rt]) ept[rt] = false;
        else if(l[rt] + 1 == r[rt]) ept[rt] = (cover[rt]==0);
        else ept[rt] = (ept[ls(rt)] or ept[rs(rt)]);
    }
    void build(int L, int R, int rt = 1){
        l[rt] = L; r[rt] = R;
        ept[rt] = true; cover[rt] = 0;
        if(l[rt] + 1 == r[rt]) return;
        int mid = (L + R) >> 1;
        build(L,mid,ls(rt)); build(mid,R,rs(rt));
    }
    void modify(int L, int R, int x, int rt  = 1){
        if(L>=r[rt] or l[rt]>=R) return;
        if(L<=l[rt] and r[rt]<=R){
            cover[rt] += x;
            pushup(rt);
            return;
        }
        modify(L,R,x,ls(rt)); modify(L,R,x,rs(rt));
        pushup(rt);
    }
    bool checkempty(){ return ept[1]; }
}ST;

vector<pair<pii,int> > seg[MAXN];

bool check(int mid){
    vector<pair<pii,pii> > rect;
    for(auto &p : vec){
        int &x = p.first, &y = p.second;
        rect << make_pair(make_pair(max(1,x-mid),max(1,y-mid)),make_pair(min(n,x+mid),min(m,y+mid)));
    }
    vector<int> vecx, vecy;
    for(auto &p : rect){
        vecx << p.first.first << p.second.first;
        vecy << p.first.second << p.second.second;
        if(p.first.first!=1) vecx << (p.first.first-1);
        if(p.first.second!=1) vecy << (p.first.second-1);
        if(p.second.first!=n) vecx << (p.second.first+1);
        if(p.second.second!=m) vecy << (p.second.second+1);
    }
    sort(all(vecx)); sort(all(vecy));
    vecx.erase(unique(all(vecx)),vecx.end());
    vecy.erase(unique(all(vecy)),vecy.end());
    for(auto &p : rect){
        p.first.first = lower_bound(all(vecx),p.first.first) - vecx.begin() + 1;
        p.second.first = lower_bound(all(vecx),p.second.first) - vecx.begin() + 1;
        p.first.second = lower_bound(all(vecy),p.first.second) - vecy.begin() + 1;
        p.second.second = lower_bound(all(vecy),p.second.second) - vecy.begin() + 1;
    }
    int x1 = n + 1, y1 = m + 1, x2 = 0, y2 = 0;
    if(vecx[0]!=1 or vecy.front()!=1 or vecy.back()!=m) x1 = 0;
    else{
        for(int i = 1; i <= (int)vecx.size(); i++) seg[i].clear();
        for(auto &p : rect){
            seg[p.first.first] << make_pair(make_pair(p.first.second,p.second.second),1);
            seg[p.second.first+1] << make_pair(make_pair(p.first.second,p.second.second),-1);
        }
        ST.build(1,vecy.size() + 1);
        for(int i = 1; i <= (int)vecx.size(); i++){
            for(auto &p : seg[i]) ST.modify(p.first.first,p.first.second+1,p.second);
            if(ST.checkempty()){
                x1 = vecx[i-1] - 1;
                break;
            }
        }
    }
    if(vecx.back()!=n or vecy.front()!=1 or vecy.back()!=m) x2 = n + 1;
    else{
        for(int i = 1; i <= (int)vecx.size(); i++) seg[i].clear();
        for(auto &p : rect){
            seg[p.first.first-1] << make_pair(make_pair(p.first.second,p.second.second),-1);
            seg[p.second.first] << make_pair(make_pair(p.first.second,p.second.second),1);
        }
        ST.build(1,vecy.size() + 1);
        for(int i = (int)vecx.size(); i >= 1; i--){
            for(auto &p : seg[i]) ST.modify(p.first.first,p.first.second+1,p.second);
            if(ST.checkempty()){
                x2 = vecx[i-1] + 1;
                break;
            }
        }
    }
    if(vecy[0]!=1 or vecx.front()!=1 or vecx.back()!=n) y1 = 0;
    else{
        for(int i = 1; i <= (int)vecy.size(); i++) seg[i].clear();
        for(auto &p : rect){
            seg[p.first.second] << make_pair(make_pair(p.first.first,p.second.first),1);
            seg[p.second.second+1] << make_pair(make_pair(p.first.first,p.second.first),-1);
        }
        ST.build(1,vecx.size() + 1);
        for(int i = 1; i <= (int)vecy.size(); i++){
            for(auto &p : seg[i]) ST.modify(p.first.first,p.first.second+1,p.second);
            if(ST.checkempty()){
                y1 = vecy[i-1] - 1;
                break;
            }
        }
    }
    if(vecy.back()!=m or vecx.front()!=1 or vecx.back()!=n) y2 = m+1;
    else{
        for(int i = 1; i <= (int)vecy.size(); i++) seg[i].clear();
        for(auto &p : rect){
            seg[p.first.second-1] << make_pair(make_pair(p.first.first,p.second.first),-1);
            seg[p.second.second] << make_pair(make_pair(p.first.first,p.second.first),1);
        }
        ST.build(1,vecx.size() + 1);
        for(int i = (int)vecy.size(); i >= 1; i--){
            for(auto &p : seg[i]) ST.modify(p.first.first,p.first.second+1,p.second);
            if(ST.checkempty()){
                y2 = vecy[i-1] + 1;
                break;
            }
        }
    }
    int dx = x2 - x1 - 1, dy = y2 - y1 - 1;
    return max(dx/2,dy/2) <= mid;
}

void solve(){
    sci(n); sci(m); sci(k);
    vec.resize(k);
    for(auto &p : vec) sci(p.first), sci(p.second);
    int l = 0, r = max(n,m);
    while(l<=r){
        int mid = (l + r) >> 1;
        if(check(mid)) r = mid - 1;
        else l = mid + 1;
    }
    cout << l << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

F. Guards In The Storehouse

这个有图比较好懂

显然是要状压\(dp\)

\(dp[i][j][mask][x][y]\)

\(i\)表示第\(i\)行,\(j\)表示第\(j\)列,\(mask\)表示到当前位置每一列上是否有没有被墙堵住的守卫,\(x\)表示同一行左边是否有没有被墙堵住的守卫,\(y\)表示是否有没有被守卫保护到的区域

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 = 1<<15;
const int MOD = 1e9+7;
const int N = 15;


int n, m, f[2][MAXN][2][2];
char buf[1<<8][1<<8], s[1<<8][1<<8];

void solve(){
    sci(n); sci(m);
    for(int i = 0; i < n; i++) scanf("%s",buf[i]);
    if(n>=m) for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) s[i][j] = buf[i][j];
    else{
        for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) s[j][i] = buf[i][j];
        swap(n,m);
    }
    int tag = 0;
    f[0][0][0][0] = 1;
    auto setzero = [&](int x, int y){ return (x>>y&1) ? (x ^ (1 << y)) : x; };
    for(int i = 0; i < n; i++) for(int j = 0; j < m; j++){
        tag ^= 1;
        memset(f[tag],0,sizeof(f[tag]));
        for(int msk = 0; msk < (1 << m); msk++){
            for(int x = 0; x < 2; x++) for(int y = 0; y < 2; y++){
                if(s[i][j]=='x') f[tag][setzero(msk,j)][0][y] = (f[tag][setzero(msk,j)][0][y] + f[tag^1][msk][x][y]) % MOD;
                else{
                    if(j==m-1){
                        if(x or (msk>>j&1)) f[tag][msk][0][y] = (f[tag][msk][0][y] + f[tag^1][msk][x][y]) % MOD;    // no guard in this cell
                        f[tag][msk|(1<<j)][0][y] = (f[tag][msk|(1<<j)][0][y] + f[tag^1][msk][x][y]) % MOD;          // set a guard
                        if(!x and !(msk>>j&1) and !y) f[tag][msk][0][1] = (f[tag][msk][0][1] + f[tag^1][msk][x][y]) % MOD;
                    }else{
                        if(x or (msk>>j&1)) f[tag][msk][x][y] = (f[tag][msk][x][y] + f[tag^1][msk][x][y]) % MOD;    // no guard in this cell
                        f[tag][msk|(1<<j)][1][y] = (f[tag][msk|(1<<j)][1][y] + f[tag^1][msk][x][y]) % MOD;          // set a guard
                        if(!x and !(msk>>j&1) and !y) f[tag][msk][0][1] = (f[tag][msk][0][1] + f[tag^1][msk][x][y]) % MOD;
                    }

                }
            }
        }
    }
    int ret = 0;
    for(int msk = 0; msk < (1 << m); msk++) for(int x = 0; x < 2; x++) for(int y = 0; y < 2; y++) ret = (ret + f[tag][msk][x][y]) % MOD;
    cout << ret << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

G. Shortest Path Problem?

可以发现如果存在环的话,这个环上的异或和是可以在任何时候被选上使用的,可以考虑从\(1\)到环上一点,然后绕一圈在回去就好了,所以可以把所有环上的值放到一个线性基里面,然后我们找到任意一条\(1\)\(n\)的路径,把这个路径异或和放到线性基里面取个\(\min\)就好了

考虑如何把所有环的异或和算出来,可以在建\(dfs\)树的过程中算,遇到一条非树边\(u,v\)之后,我们把\(dis_u\oplus dis_v\oplus w_{uv}\)放到线性基里面

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, m, vis[MAXN], dis[MAXN];
vector<pii> G[MAXN];
int base[30];
void ins(int x){
    for(int i = 29; ~i; i--){
        if(x>>i&1){
            if(!base[i]){
                base[i] = x;
                break;
            }
            x ^= base[i];
        }
    }
}

int get_min(int x){
    for(int i = 29; ~i; i--){
        if(x>>i&1 and base[i]) x ^= base[i];
    }
    return x;
}

void dfs(int u, int par){
    vis[u] = true;
    bool findpar = false;
    for(auto &e : G[u]){
        int v = e.first, w = e.second;
        if(v==par and !findpar){
            findpar = true;
            continue;
        }
        if(!vis[v]){
            dis[v] = dis[u] ^ w;
            dfs(v,u);
        }else ins(dis[u] ^ dis[v] ^ w);
    }
}

void solve(){
    sci(n); sci(m);
    for(int i = 1; i <= m; i++){
        int u, v, w; sci(u); sci(v); sci(w);
        G[u] << pii(v,w); G[v] << pii(u,w);
    }
    dfs(1,0);
    cout << get_min(dis[n]) << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}
posted @ 2020-08-24 21:04  _kiko  阅读(147)  评论(0编辑  收藏  举报