• 【AtCoder】ARC076


    ARC076

    C - Reconciled?

    如果(N = M)

    答案是(2N!M!)

    如果(|N - M| = 1)

    答案是(N!M!)

    否则答案是0

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define eps 1e-10
    #define MAXN 100005
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef unsigned int u32;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 +c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) {
    	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    const int MOD = 1000000007;
    int N,M;
    int fac[MAXN];
    int inc(int a,int b) {
        return a + b >= MOD ? a + b - MOD : a + b;
    }
    int mul(int a,int b) {
        return 1LL * a * b % MOD;
    }
    void Solve() {
        read(N);read(M);
        if(abs(N - M) > 1) {puts("0");return;}
        fac[0] = 1;
        for(int i = 1 ; i <= max(N,M) ; ++i) {
    	fac[i] = mul(fac[i - 1],i);
        }
    
        int ans = mul(fac[N],fac[M]);
        if(N == M) {
    	ans = mul(ans,2);
        }
        out(ans);enter;
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
    }
    

    D - Built?

    发现横坐标排序和纵坐标排序后,只有相邻的边会有边

    然后跑最小生成树即可

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define eps 1e-10
    #define MAXN 100005
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef unsigned int u32;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 +c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) {
    	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    const int MOD = 1000000007;
    int N;
    int x[MAXN],y[MAXN];
    int id[MAXN],cnt,fa[MAXN];
    struct node {
        int u,v,c;
    }E[MAXN * 10];
    int getfa(int u) {
        return fa[u] == u ? u : fa[u] = getfa(fa[u]);
    }
    void Solve() {
        read(N);
        for(int i = 1 ; i <= N ; ++i) {read(x[i]);read(y[i]);}
        for(int i = 1 ; i <= N ; ++i) id[i] = i;
        sort(id + 1,id + N + 1,[](int a,int b) {return x[a] < x[b];});
        for(int i = 1 ; i < N ; ++i) {
    	E[++cnt] = (node){id[i],id[i + 1],x[id[i + 1]] - x[id[i]]};
        }
        for(int i = 1 ; i <= N ; ++i) id[i] = i;
        sort(id + 1,id + N + 1,[](int a,int b) {return y[a] < y[b];});
        for(int i = 1 ; i < N ; ++i) {
    	E[++cnt] = (node){id[i],id[i + 1],y[id[i + 1]] - y[id[i]]};
        }
        sort(E + 1,E + cnt + 1,[](node a,node b){return a.c < b.c;});
        for(int i = 1 ; i <= N ; ++i) fa[i] = i;
        int ans = 0;
        for(int i = 1 ; i <= cnt ; ++i) {
    	if(getfa(E[i].u) != getfa(E[i].v)) {
    	    ans += E[i].c;
    	    fa[getfa(E[i].u)] = getfa(E[i].v);
    	}
        }
        out(ans);enter;
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
    }
    

    E - Connected?

    只有两个点都在边上的连线才有影响,我们把这些点按照顺时针(逆时针也可以)扔进栈里,栈顶元素和它相同则弹出,如果最后栈是空的就合法,否则就不合法

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define eps 1e-10
    #define MAXN 100005
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef unsigned int u32;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 +c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) {
    	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    struct node {
        int x,y,p;
    };
    int R,C;
    int N;
    int x[MAXN][2],y[MAXN][2];
    vector<node> v[4];
    int sta[MAXN * 2],top;
    bool on_u(int x,int y) {
        return x == 0;
    }
    bool on_l(int x,int y) {
        return x != 0 && x != R && y == 0;
    }
    bool on_r(int x,int y) {
        return x != 0 && x != R && y == C;
    }
    bool on_d(int x,int y) {
        return x == R;
    }
    bool check(int x,int y) {
        return on_u(x,y) || on_l(x,y) || on_r(x,y) || on_d(x,y);
    }
    int id(int x,int y) {
        if(on_u(x,y)) return 0;
        else if(on_r(x,y)) return 1;
        else if(on_d(x,y)) return 2;
        else return 3;
    }
    void Solve() {
        read(R);read(C);read(N);
        for(int i = 1 ; i <= N ; ++i) {
    	for(int j = 0 ; j <= 1 ; ++j) {read(x[i][j]);read(y[i][j]);}
    	if(check(x[i][0],y[i][0]) && check(x[i][1],y[i][1])) {
    	    v[id(x[i][0],y[i][0])].pb((node){x[i][0],y[i][0],i});
    	    v[id(x[i][1],y[i][1])].pb((node){x[i][1],y[i][1],i});
    	}
        }
        sort(v[0].begin(),v[0].end(),[](node a,node b){return a.y < b.y;});
        sort(v[1].begin(),v[1].end(),[](node a,node b){return a.x < b.x;});
        sort(v[2].begin(),v[2].end(),[](node a,node b){return a.y > b.y;});
        sort(v[3].begin(),v[3].end(),[](node a,node b){return a.x > b.x;});
        for(int i = 0 ; i < 4 ; ++i) {
    	for(auto t : v[i]) {
    	    if(sta[top] == t.p) --top;
    	    else sta[++top] = t.p;
    	}
        }
        if(top) puts("NO");
        else puts("YES");
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
    }
    

    F - Exhausted?

    线段树维护hall定理,好像之前遇到过类似的但是没有写这个做法。。。

    hall定理是什么呢

    (X,Y)为两边的点集,(X)(Y)之间存在完美匹配,仅当(X)中任意(k)个点组成的点集和(Y)中的至少(k )个点相连

    这是充分必要的

    那么我们求的是人数-最大匹配,也就是每个点集减去匹配(Y)点集椅子个数的最大值,初始的答案先设成(max(N - M,0))

    设点集大小为(|X|),匹配(Y)点集的椅子数是(Gamma(X))

    答案显然不小于((|X| - |Gamma(X)|)_{max})

    如果答案大于((|X| - |Gamma(X)|)_{max}),设(t > (|X| - |Gamma(X)|)_{max}),如果当前存在一个大于t的未匹配点,那么选这t个点一定与对面至少一个点相连,设为(v),若v被匹配,找到匹配点u,u与这t个点组成的点集匹配至少两个点,所以可以增加一个匹配点,可以证明答案不大于((|X| - |Gamma(X)|)_{max})

    所以只要考虑怎么求((|X| - |Gamma(X)|)_{max})

    显然是对于一个固定的区间,计算多少个点的(L_{i},R_{i})覆盖了这个区间,所以把区间按左端点排序,然后线段树维护即可

    #include <bits/stdc++.h>
    #define fi first
    #define se second
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define space putchar(' ')
    #define enter putchar('
    ')
    #define eps 1e-10
    #define MAXN 200005
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef unsigned int u32;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
    	if(c == '-') f = -1;
    	c = getchar();
        }
        while(c >= '0' && c <= '9') {
    	res = res * 10 +c - '0';
    	c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) {
    	out(x / 10);
        }
        putchar('0' + x % 10);
    }
    int N,M;
    struct node {
        int l,r;
    }p[MAXN];
    struct seg_tree {
        int l,r;
        int lz,mx;
    }tr[MAXN * 4];
    void update(int u) {
        tr[u].mx = max(tr[u << 1 | 1].mx,tr[u << 1].mx);
    }
    void addlz(int u,int v) {
        tr[u].mx += v;tr[u].lz += v;
    }
    void pushdown(int u) {
        if(tr[u].lz) {
    	addlz(u << 1,tr[u].lz);
    	addlz(u << 1 | 1,tr[u].lz);
    	tr[u].lz = 0;
        }
    }
    void build(int u,int l,int r) {
        tr[u].l = l;tr[u].r = r;
        if(l == r) {
    	tr[u].mx = r;
    	return;
        }
        int mid = (l + r) >> 1;
        build(u << 1,l,mid);
        build(u << 1 | 1,mid + 1,r);
        update(u);
    }
    void Change(int u,int l,int r,int v) {
        if(tr[u].l == l && tr[u].r == r) {addlz(u,v);return;}
        pushdown(u);
        int mid = (tr[u].l + tr[u].r) >> 1;
        if(r <= mid) Change(u << 1,l,r,v);
        else if(l > mid) Change(u << 1 | 1,l,r,v);
        else {Change(u << 1,l,mid,v);Change(u << 1 | 1,mid + 1,r,v);}
        update(u);
    }
    int Query(int u,int l,int r) {
        if(tr[u].l == l && tr[u].r == r) {return tr[u].mx;}
        pushdown(u);
        int mid = (tr[u].l + tr[u].r) >> 1;
        if(r <= mid) return Query(u << 1,l,r);
        else if(l > mid) return Query(u << 1 | 1,l,r);
        else return max(Query(u << 1,l,mid),Query(u << 1 | 1,mid + 1,r));
    }
    void Solve() {
        read(N);read(M);
        for(int i = 1 ; i <= N ; ++i) {
    	read(p[i].l);read(p[i].r);
        }
        build(1,1,M + 1);
        sort(p + 1,p + N + 1,[](node a,node b){return a.l < b.l || (a.l == b.l && a.r > b.r);});
        int ans = max(0,N - M);
        for(int i = 1 ; i <= N ; ++i) {
    	Change(1,p[i].l + 1,p[i].r,1);
    	int t = Query(1,p[i].l + 1,M + 1) - M - p[i].l - 1;
    	ans = max(ans,t);
        }
        out(ans);enter;
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
    }
    
  • 相关阅读:
    Educational Codeforces Round 10 C. Foe Pairs 水题
    Educational Codeforces Round 10 B. z-sort 构造
    CDOJ 1048 Bob's vector 三分
    Educational Codeforces Round 10 A. Gabriel and Caterpillar 模拟
    第14届电子科大初赛民间盗版部分题目题解
    HDU 5654 xiaoxin and his watermelon candy 离线树状数组 区间不同数的个数
    HDU 5653 Bomber Man wants to bomb an Array. dp
    HDU 5652 India and China Origins 二分+并查集
    HDU 5651 xiaoxin juju needs help 数学
    HDU 5650 so easy 数学
  • 原文地址:https://www.cnblogs.com/ivorysi/p/10617304.html
Copyright © 2020-2023  润新知