• 2019ICPC 上海现场赛


    网址:https://ac.nowcoder.com/acm/contest/4370

    B. Prefix Code

    阅读理解,用个set维护下就行

    #include <stdio.h>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <map> 
    #include <stack>
    #include <sstream>
    #include <set>
    // #pragma GCC optimize(2)
    
    //#define int long long
    #define ls u<<1
    #define rs u<<1|1
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define REP(i,a,n) for(int i=a;i>=n;--i)
    #define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti)
    #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    #define mm(i,v) memset(i,v,sizeof i);
    #define mp(a, b) make_pair(a, b)
    #define pi acos(-1)
    #define fi first
    #define se second
    
    using namespace std;
    typedef long long ll;
    typedef double db;
    typedef pair<ll, ll > PII;
    priority_queue< PII, vector<PII>, greater<PII> > que;
    stringstream ssin; //  ssin << string   while ( ssin >> int)
    const ll LINF = 0x7fffffffffffffffll;
    
    const int N = 4e5 + 5, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f;
    int _, n;
    string s, t;
    set<string>s1, s2;
    vector<string>vec;
    
    inline ll read() {
        char c=getchar();ll x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
        return x*f;
    }
    
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
            freopen("out.txt","w",stdout);
        #endif
    
        int cas = 0;
        _ = read();
        while (_--) {
            s1.clear();
            s2.clear();
            vec.clear();
    
            n = read();
            bool f = 1;
            rep(i, 1, n) {
                cin >> s;
                if (s1.find(s) != s1.end()) f = 0;
                s1.insert(s);
                vec.push_back(s);
            }
            rep(i, 0, n - 1) {
                s = vec[i];
                t.clear();
                for (int i = 0; i < s.size() - 1; ++i) {
                    t += s[i];
                    if (s1.find(t) != s1.end()) {
                        f = 0;
                        break;
                    }
                    if (!f) break;
                }
                if (!f) break;
            }
            printf("Case #%d: ", ++cas);
            if (f) puts("Yes");
            else puts("No");
        }
    
        // #ifndef ONLINE_JUDGE
        //     system("pause");
        // #endif
    }

    K. Color Graph

    二分图签到

    题意可以转化为判奇环,可以发现n很小,二进制枚举每个点的状态,然后直接判断即可

    #include <stdio.h>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <map> 
    #include <stack>
    #include <sstream>
    #include <set>
    #pragma GCC optimize(2)
    
    //#define int long long
    #define mm(i,v) memset(i,v,sizeof i);
    #define mp(a, b) make_pair(a, b)
    #define pi acos(-1)
    #define fi first
    #define se second
    //你冷静一点,确认思路再敲!!! 
    
    using namespace std;
    typedef long long ll;
    typedef pair<int, int > PII;
    priority_queue< PII, vector<PII>, greater<PII> > que;
    stringstream ssin; //  ssin << string   while ( ssin >> int)
    
    const int N = 500, mod = 1e9 + 9, INF = 0x3f3f3f3f;
    int t, n, m, idx, id, pos, Max;
    int e[N], h[N], ne[N], col[20];
    bool flag;
    
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
        return x*f;
    }
    
    void add(int a, int b) {
        e[idx] = b;
        ne[idx] = h[a];
        h[a] = idx++;
    }
    
    vector<PII> vec;
    int main()
    {
        cin >> t;
        while (t--) {
            vec.clear();
            Max = -1;
            mm(h, -1);
            idx = 0;
            cin >> n >> m;
            for (int i = 1; i <= m; ++i) {
                int a, b;
                cin >> a >> b;
                vec.push_back(mp(a, b));
            }
            for (pos = 0; pos <= (1 << n); ++pos) {
                mm(col, 0);
                flag = 1;
                for (int i = 1; i <= n; ++i) {
                    if ((pos >> i) & 1 && !col[i]) {
                        col[i] = 1;
                    }
                }
                int ans = 0;
                for (int i = 0; i < vec.size(); ++i) {
                    int x = vec[i].first, y = vec[i].second;
                    if (col[x] != col[y]) ans++;
                }
                Max = max(Max, ans);
                
            }
            printf("Case #%d: %d
    ", ++id, Max);
        }
        // system("pause");
        return 0;
    }

    E. Cave Escape

    可以发现起点和终点并不影响选择的路径,所以只需要对点建边求最大生成树即可

    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    using namespace std;
    const int man = 1e3+10;
    #define IOS ios::sync_with_stdio(0)
    template <typename T>
    inline T read(){T sum=0,fl=1;int ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-')fl=-1;
    for(;isdigit(ch);ch=getchar())sum=sum*10+ch-'0';
    return sum*fl;}
    template <typename T>
    inline void write(T x) {static int sta[35];int top=0;
    do{sta[top++]= x % 10, x /= 10;}while(x);
    while (top) putchar(sta[--top] + 48);}
    template<typename T>T gcd(T a, T b) {return b==0?a:gcd(b, a%b);}
    template<typename T>T exgcd(T a,T b,T &g,T &x,T &y){if(!b){g = a,x = 1,y = 0;}
    else {exgcd(b,a%b,g,y,x);y -= x*(a/b);}}
    #ifndef ONLINE_JUDGE
    #define debug(fmt, ...) {printf("debug ");printf(fmt,##__VA_ARGS__);puts("");}
    #else
    #define debug(fmt, ...)
    #endif
    typedef long long ll;
    const ll mod = 1e9+7;
    int x[man*man],fa[man*man],va[man][man];
    int sz[man*man];
    vector<pair<int,int> >A[10010];
    int find(int x){
        return x == fa[x] ? x : fa[x] = find(fa[x]);
    }
    /*
    int find(int x){
        int p = x;
        while(p!=fa[p])p = fa[p];
        while(x!=p){
            int tp = fa[x];
            fa[x] = p;
            x = tp;
        }
        return p;
    }*/
     
    bool _union(int u,int v){
       // cout << u << " 1" " << v <<endl;
        u = find(u);
        v = find(v);
      //  cout << u << " 2" " << v << endl;
        if(u==v)return true;
        if(sz[u]>sz[v]){
            sz[u] += sz[v];
            fa[v] = u;
        }else fa[u] = v,sz[v] += sz[u];
        return false;
    }
     
    int main() {
        #ifndef ONLINE_JUDGE
            //freopen("in.txt", "r", stdin);
            //freopen("out.txt","w",stdout);
        #endif
        int t;
        scanf("%d",&t);
        int T = 0;
        while(t--){
            int n,m,s,a,b,c,p;
            for(int i = 0;i <= 10000;i++)A[i].clear();
            scanf("%d%d%d%d%d%d",&n,&m,&s,&s,&s,&s);
            scanf("%d%d%d%d%d%d",x+1,x+2,&a,&b,&c,&p);
            fa[1] = 1;
            fa[2] = 2;
            for(int i = 3;i <= n*m;i++){
                fa[i] = i;
                sz[i] = 1;
                x[i] = (a*x[i-1] + b*x[i-2] + c)%p;
            }
            int cnt = 0;
            for(int i = 1;i <= n;i++){
                for(int j = 1;j <= m;j++){
                    va[i][j] = x[(i-1)*m + j];
                    if(!va[i][j])continue;
                    if(i>1&&va[i-1][j])A[va[i][j]*va[i-1][j]].push_back(make_pair((i-1)*m + j,(i-2)*m + j));
                    if(j>1&&va[i][j-1])A[va[i][j]*va[i][j-1]].push_back(make_pair((i-1)*m + j,(i-1)*m + j - 1));
                }
            }
    
            ll ans = 0;
            int res = 0;
            for(int j = 10000;j >= 0;j--){
                for(int i = 0;i < A[j].size();i++){
                    int u = A[j][i].first;
                    int v = A[j][i].second;
                    //cout << A[i].w << endl;
                    // if(!_union(u,v)){
                    // }
                    if (find(u) == find(v)) continue;
                    int pa = find(u), pb = find(v);
                    fa[pa] = pb;
                    ans += j;
                    res++;
                    if(res==n*m-1)break;
                }
                if(res==n*m-1)break;
            }
             
            printf("Case #%d: %lld
    ",++T,ans);
        }
        return 0;
    }

    H. Tree Partition

    二分+贪心

    对于每棵树一定是去掉最大的子树最优

    #include <stdio.h>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <map> 
    #include <stack>
    #include <sstream>
    #include <set>
    // #pragma GCC optimize(2)
    
    //#define int long long
    #define ls u<<1
    #define rs u<<1|1
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define REP(i,a,n) for(int i=a;i>=n;--i)
    #define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti)
    #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    #define mm(i,v) memset(i,v,sizeof i);
    #define mp(a, b) make_pair(a, b)
    #define pi acos(-1)
    #define fi first
    #define se second
    
    using namespace std;
    typedef long long ll;
    typedef double db;
    typedef pair<ll, ll > PII;
    priority_queue< PII, vector<PII>, greater<PII> > que;
    stringstream ssin; //  ssin << string   while ( ssin >> int)
    const ll LINF = 0x7fffffffffffffffll;
    
    const int N = 4e5 + 5, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f;
    int _, n, k, idx;
    int e[M], ne[M], h[N];
    int flag, cnt;
    ll sum[N], a[N];
    
    inline ll read() {
        char c=getchar();ll x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
        return x*f;
    }
    
    void add(int a, int b) {
        e[idx] = b;
        ne[idx] = h[a];
        h[a] = idx++;
    }
    
    void dfs(int u, int fa, ll mid) {
        sum[u] = a[u];
        if (sum[u] > mid || flag) {
            flag = 1;
            return;
        }
    
        for (int i = h[u]; ~i; i = ne[i]) {
            int v = e[i];
            if (v == fa) continue;
            dfs(v, u, mid);
            sum[u] += sum[v];
        }
    
        if (sum[u] > mid) {
            vector<ll>vec;
            for (int i = h[u]; ~i; i = ne[i]) {
                int v = e[i];
                if (v == fa) continue;
                vec.push_back(sum[v]);
            }
            sort(vec.begin(), vec.end());
            for (int i = vec.size() - 1; i >= 0; --i) {
                if (sum[u] <= mid) break;
                sum[u] -= vec[i];
                cnt++;
            }
        }
        if (cnt > k - 1) {
            flag = 1;
        }
    }
    
    bool ck(ll mid) {
        cnt = flag = 0;
        dfs(1, -1, mid);
        if (flag) return false;
        return true;
    }
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
            freopen("out.txt","w",stdout);
        #endif
        _ = read();
        ll cas = 0, ans;
        while (_--) {
            n = read(); k = read();
            idx = 0;
            for (int i = 0; i <= n; ++i) h[i] = -1;
            rep(i, 1, n - 1) {
                int u, v;
                u = read(); v = read();
                add(u, v);
                add(v, u);
            }
            rep(i, 1, n) a[i] = read();
    
            ll l = 0ll, r = 1e14;
            while (l < r) {
                ll mid = l + r >> 1;
                if (ck(mid)) {
                    r = mid;
                    ans = mid;
                } else {
                    l = mid + 1;
                }
            }
    
            printf("Case #%lld: %lld
    ", ++cas, l);
        }
    
        // #ifndef ONLINE_JUDGE
        //     system("pause");
        // #endif
    }

    D. Spanning Tree Removal

    构造,对于每棵树 i,i + 1, i - 1, i + 2, i - 2, i + 3, i - 2......

    #include <stdio.h>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <map> 
    #include <stack>
    #include <sstream>
    #include <set>
    // #include <unordered_set>
    // #pragma GCC optimize(2)
    
    //#define int long long
    #define ls u<<1
    #define rs u<<1|1
    #define rep(i,a,n) for(int i=a;i<=n;i++)
    #define REP(i,a,n) for(int i=a;i>=n;--i)
    #define rush() int T;scanf("%d",&T);for(int Ti=1;Ti<=T;++Ti)
    #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    #define mm(i,v) memset(i,v,sizeof i);
    #define mp(a, b) make_pair(a, b)
    #define pi acos(-1)
    #define fi first
    #define se second
    
    using namespace std;
    typedef long long ll;
    typedef double db;
    typedef pair<ll, ll > PII;
    priority_queue< PII, vector<PII>, greater<PII> > que;
    stringstream ssin; //  ssin << string   while ( ssin >> int)
    const ll LINF = 0x7fffffffffffffffll;
    
    const int N = 1e3 + 5, M = 4e5 + 5, mod = 1e9 + 7, INF = 0x3f3f3f3f;
    int _, n;
    vector<PII>vec;
    bool vis[N];
    
    inline ll read() {
        char c=getchar();ll x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
        return x*f;
    }
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("in.txt","r",stdin);
            freopen("out.txt","w",stdout);
        #endif
        int cas = 0;
        _ = read();
        while (_--) {
            n = read();
            printf("Case #%d: %d
    ", ++cas, n / 2);
            rep(i, 1, n / 2) {
                int now = i - 1;
                printf("%d %d
    ", now % n + 1, (now + 1) % n + 1);
                for (int j = 2; j <= n - 1; ++j) {
                    if (j & 1) printf("%d %d
    ", (now - j / 2 + n) % n + 1, (now + j / 2 + 1) % n + 1);
                    else printf("%d %d
    ", (now + j / 2) % n + 1, (now - j / 2 + n) % n + 1);
                }
            }
        }
        // #ifndef ONLINE_JUDGE
        //     system("pause");
        // #endif
    }
  • 相关阅读:
    CF1051D Bicolorings dp
    loj2480 [CEOI2017]One-Way Streets 边双+树上差分
    有趣的支配树
    AtCoder Regular Contest 81
    [BZOJ5305][HAOI2018]苹果树(DP)
    [BZOJ4699]树上的最短路(最短路+线段树)
    [BZOJ3507][CQOI2014]通配符匹配(DP+Hash)
    [Luogu4724][模板]三维凸包(增量构造法)
    [BZOJ5317][JSOI2018]部落战争(闵可夫斯基和)
    [WC2014]时空穿梭(莫比乌斯反演)
  • 原文地址:https://www.cnblogs.com/mwh123/p/14044756.html
Copyright © 2020-2023  润新知