zoukankan      html  css  js  c++  java
  • Codeforces Round #628 (Div. 2)

    传送门

    A. EhAb AnD gCd

    签到。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/14 22:35:47
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
     
    void run() {
        int n; cin >> n;
        cout << 1 << ' ' << n - 1 << '
    ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        int T; cin >> T;
        while(T--) run();
        return 0;
    }
    

    B. CopyCopyCopyCopyCopy

    因为是严格上升子序列,所以每个数至多被选择一次。
    最后答案即为数组中互不重复的数字个数。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/14 22:43:53
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
     
    void run() {
        int n; cin >> n;
        vector <int> a(n);
        for(int i = 0; i < n; i++) cin >> a[i];
        sort(all(a));
        a.erase(unique(all(a)), a.end());
        cout << sz(a) << '
    ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        int T; cin >> T;
        while(T--) run();
        return 0;
    }
    

    C. Ehab and Path-etic MEXs

    贪心。从叶子结点开始放置即可。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/14 22:50:27
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
     
    int n;
    vector <int> G[N];
    int ans[N];
     
    void run() {
        cin >> n;
        for(int i = 1; i < n; i++) {
            int u, v; cin >> u >> v;
            G[u].push_back(i);
            G[v].push_back(i);
        }
        memset(ans, -1, sizeof(ans));
        int now = 0;
        for(int i = 1; i <= n; i++) if(sz(G[i]) == 1){
            for(auto it : G[i]) if(ans[it] == -1) ans[it] = now++;   
        }
        for(int i = 1; i < n; i++) if(ans[i] == -1) ans[i] = now++;
        for(int i = 1; i < n; i++) cout << ans[i] << '
    ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    D. Ehab the Xorcist

    题意:
    给出两个数(u,v,0leq u,vleq 10^{18})
    构造长度最小的数组,使得数组中所有元素的异或和为(u),所有元素的和为(v)

    思路:

    • 按二进制位来考虑,令数组中一个元素为(u),因为这些二进制位必须有,那么(vgeq u)才合法。
    • (d=v-u),考虑(d)的二进制位。若干(d)在第(k)位为(1),那么我们可以将其加在这一位上,或者加两倍在第(k-1)位上。因为要满足异或关系,所以不能改变二进制位的奇偶性,所以我们选择加两倍在(k-1)位上。若不能加则不合法。
    • 那么现在得到了(cnt[i])表示第(i)个二进制位为几倍,那么最终数组个数即为(max{cnt_i})。贪心得到数组元素即可。

    代码如下:

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/14 23:13:48
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 64;
     
    int cnt[N], need[N];
     
    void run() {
        ll u, v; cin >> u >> v;
        for(int i = 0; i < N; i++) if(u >> i & 1) ++cnt[i];
        if(u > v) {
            cout << -1 << '
    ';
            return;   
        }
        ll d = v - u;
        for(int i = N - 1; i >= 0; i--) if(d >> i & 1) {
            if(i) cnt[i - 1] += 2;
            else {
                cout << -1 << '
    ';
                return;
            }
        }
        vector <ll> ans;
        while(1) {
            bool ok = false;
            for(int i = 0; i < N; i++) if(cnt[i]) ok = true;   
            if(!ok) break;
            ll res = 0;
            for(int i = 0; i < N; i++) if(cnt[i]) {
                res += 1ll << i;
                --cnt[i];   
            }
            ans.push_back(res);
        }
        cout << sz(ans) << '
    ';
        for(auto it : ans) cout << it << ' ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    E. Ehab's REAL Number Theory Problem

    题意:
    给出(a_{1,2,...,n},nleq 10^5,a_ileq 10^6),保证每个元素至多(7)个因子。
    现在要从序列中选择长度最少的数,使得其乘积为完全平方数。

    思路:

    • 由每个元素至多(7)个因子我们可以知道每个元素至多两个素因子,并且有如下几种形式:(p,p^2,pq,p^2q)
    • 乘积为完全平方数则等价于乘积的素因子指数都为偶数。据此显然(p^2q)(q)这种形式等价。
    • 对于(p^2)这种形式,我们可以直接单独考虑,那么最后就只剩下(p,pq)这两种形式。我们现在要选取最少的数,使得其乘积为完全平方数。也就是最后每个质因子的指数为(2)
    • 我们将(p)抽象为((1,p),pq)抽象为((p,q))。那么问题等价于求一个长度最小的环。因为环中每个点的度数为(2),也就是每个质因子的指数为(2)
    • 直接通过(dfs)树或者(bfs)树来求解的话时间复杂度为(O(n^2))。注意到一个环中最多只有(1)个数大于(1000),那么我们枚举所有不超过(1000)的数找环即可。

    一点题外话:
    最终通过(dfs)树或者(bfs)树来找环感觉有点迷。因为从一个点出发不能找出所有的环。(bfs)树还好,能找到起点所在的所有环;(dfs)树应该是找到所有依附于(dfs)树上的边的所有环,这样的话(dfs)的顺序不同找到的环也可能不同,感觉可能就存在随机性?
    但代码我是直接(dfs)的,也通过了所有样例。
    如果有大佬知道其中的一些原理,希望能不吝赐教。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/15 11:47:16
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e6 + 5;
     
    int n;
    int a[N];
    int vis1[N];
    map <pii, int> vis2;
    vector <int> v[N];
    int mp[N], tot;
     
    int dep[N];
    vector <int> G[N];
    int ans;
     
    void dfs(int u, int fa) {
        dep[u] = dep[fa] + 1;
        for(auto v : G[u]) if(v != fa) {
            if(dep[v] == 0) dfs(v, u);
            else if(dep[u] > dep[v]) {
                ans = min(ans, dep[u] - dep[v] + 1);   
            }
        }
    }
     
    void run() {
        cin >> n;
        bool ok = false;
        for(int i = 1; i <= n; i++) {
            cin >> a[i];
            if(a[i] == 1) ok = true;
            int t = a[i], num = 0;
            for(int x = 2; 1ll * x * x <= a[i]; x++) {
                if(a[i] % x == 0) {
                    int cnt = 0;
                    while(a[i] % x == 0) a[i] /= x, ++cnt;
                    if(cnt & 1) v[i].push_back(x);
                    else ++num;
                }   
            }
            if(a[i] > 1) v[i].push_back(a[i]);
            if(num && !sz(v[i])) ok = true;
            a[i] = t;
        }
        if(ok) {
            cout << 1 << '
    '; return;   
        }
        for(int i = 1; i <= n; i++) {
            if(sz(v[i]) == 1) {
                int from = 1, to = v[i][0];
                if(!mp[from]) mp[from] = ++tot;
                if(!mp[to]) mp[to] = ++tot;
                G[mp[from]].push_back(mp[to]);
                G[mp[to]].push_back(mp[from]);
                if(++vis1[v[i][0]] > 1) {
                    cout << 2 << '
    '; return;
                }
            }
            if(sz(v[i]) == 2) {
                int from = v[i][0], to = v[i][1];
                if(!mp[from]) mp[from] = ++tot;
                if(!mp[to]) mp[to] = ++tot;
                G[mp[from]].push_back(mp[to]);
                G[mp[to]].push_back(mp[from]);
                if(++vis2[MP(from, to)] > 1) {
                    cout << 2 << '
    '; return;   
                }
            }
        }
        ans = INF;
        for(int i = 1; i <= 1000; i++) if(mp[i]) {
            for(int j = 1; j <= tot; j++) dep[j] = 0;
            dfs(mp[i], 0);
        }
        if(ans == INF) ans = -1;
        cout << ans << '
    ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    F. Ehab's Last Theorem

    题意:
    给出(n)个点,(m)条边的无向图。
    现在要找到:

    • 刚好有(lceilsqrt{n} ceil)个点的独立集;
    • 长度至少为(lceilsqrt{n} ceil)的环。

    找到其中一个即可。

    思路:
    (sq=lceilsqrt{n} ceil)

    • 环显然比直接找独立集好找,我们可以直接通过(dfs)树来找环。
    • 构建出(dfs)树后,若找不到长度不小于(sq)的环。我们将结点深度按照(\%(sq-1))进行分类。因为不存在环,那么显然现在任意同类的结点直接不会存在边。
    • 根据抽屉原理,必然会存在一类,其结点个数不小于(sq)。那么直接贪心找即可。

    这个题也很巧妙,主要是(dfs)树的运用。题解中提到了一篇博客,写得挺细致的:传送门
    代码如下:

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/15 10:36:27
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
     
    int n, m, sq;
    vector <int> G[N];
     
    int dep[N];
    vector <int> cyc;
    void dfs(int u) {
        cyc.push_back(u);
        dep[u] = sz(cyc) - 1;
        for(auto v : G[u]) {
            if(dep[v] != -1) {
                if(dep[u] - dep[v] + 1 >= sq) {
                    cout << 2 << '
    ';
                    cout << dep[u] - dep[v] + 1 << '
    ';
                    while(1) {
                        int now = cyc.back();
                        cout << now << ' ';
                        if(now == v) break;
                        cyc.pop_back();
                    }
                    exit(0);
                }         
            } else dfs(v);   
        }
        cyc.pop_back();
    }
     
    int cnt[N];
     
    void run() {
        memset(dep, -1, sizeof(dep));
        cin >> n >> m;
        for(int i = 1; i <= m; i++) {
            int u, v; cin >> u >> v;
            G[u].push_back(v);
            G[v].push_back(u);   
        }
        sq = 1;
        while(1ll * sq * sq < n) ++sq;
        dfs(1);
        for(int i = 1; i <= n; i++) ++cnt[dep[i] % (sq - 1)];
        int Max = *max_element(cnt, cnt + n + 1);
        cout << 1 << '
    ';
        vector <int> ans;
        for(int i = 1; i <= n; i++) if(cnt[dep[i] % (sq - 1)] == Max) ans.push_back(i);
        ans.resize(sq);
        for(auto it : ans) cout << it << ' ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    
  • 相关阅读:
    放射渐变RadialGradient
    return columns.All(new Func<string, bool>(list.Contains));
    AspnetIdentitySample
    Request.GetOwinContext()打不到
    EntityFramework系列:SQLite.CodeFirst自动生成数据库
    EF 索引
    Using Friendly URLs in ASP.NET Web Forms
    OWIN support for the Web API 2 and MVC 5 integrations in Autofac
    owin
    owin中间件
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/12502362.html
Copyright © 2011-2022 走看看