• 《Deltix Round, Autumn 2021 (open for everyone, rated, Div. 1 + Div. 2)》


    感觉这场题面有点绕

    A:先把能除2的都除2,然后最后再把最大的不断翻倍即可

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const int N = 2e3 + 5;
    const int M = 1e4 + 5;
    const LL Mod = 1e9 + 7;
    #define rep(at,am,as) for(int at = am;at <= as;++at)
    #define ret(at,am,as) for(int at = am;at >= as;--at)
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline long long ADD(long long x,long long y) {
        if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
        return (x + y) % Mod;
    }
    inline long long MUL(long long x,long long y) {
        if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
        return x * y % Mod;
    }
    inline long long DEC(long long x,long long y) {
        if(x - y < 0) return (x - y + Mod) % Mod;
        return (x - y) % Mod;
    }
    
    int n,a[N];
    void solve() {
        scanf("%d",&n);
        for(int i = 1;i <= n;++i) scanf("%d",&a[i]);
        int cnt = 0,pos;
        LL mx = 0;
        for(int i = 1;i <= n;++i) {
            while(a[i] % 2 == 0) a[i] /= 2,++cnt;
            if(a[i] * 1LL > mx) mx = a[i],pos = i;
        }
        LL ans = 0;
        for(int i = 1;i <= n;++i) {
            if(i != pos) ans += a[i];
            else {
                LL tmp = a[i];
                for(int j = 1;j <= cnt;++j) tmp *= 2;
                ans += tmp;
            }
        }
        printf("%lld\n",ans);
    
    }   
    int main() {
        int _;
        for(scanf("%d",&_);_;_--) {
            solve();
        }
        //system("pause");
        return 0;
    }
    View Code

    B:演爆了。

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const int N = 1e5 + 5;
    const int M = 1e4 + 5;
    const LL Mod = 1e9 + 7;
    #define rep(at,am,as) for(int at = am;at <= as;++at)
    #define ret(at,am,as) for(int at = am;at >= as;--at)
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline long long ADD(long long x,long long y) {
        if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
        return (x + y) % Mod;
    }
    inline long long MUL(long long x,long long y) {
        if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
        return x * y % Mod;
    }
    inline long long DEC(long long x,long long y) {
        if(x - y < 0) return (x - y + Mod) % Mod;
        return (x - y) % Mod;
    }
    
    char s[N];
    int n,q;
    bool check(int id,char t) {
        if(id <= n - 2 && t == 'a' && s[id] == 'b' && s[id + 1] == 'c') return true;
        if(id <= n - 1 && id >= 2 && t == 'b' && s[id - 2] == 'a' && s[id] == 'c') return true;
        if(id >= 3 && t == 'c' && s[id - 2] == 'b' && s[id - 3] == 'a') return true;
        return false;
    }
    
    void solve() {
        scanf("%d %d",&n,&q);
        cin >> s;
        int ans = 0;
        for(int i = 0;i < n;++i) {
            if(i + 2 >= n) break;
            if(s[i] == 'a' && s[i + 1] == 'b' && s[i + 2] == 'c') ans++;
        }
        while(q--) {
            int id;
            string t;
            cin >> id >> t;
            if(t[0] == s[id - 1]) {printf("%d\n",ans);continue;}
            if(check(id,t[0])) ans++;
            if(check(id,s[id - 1])) ans--;
            printf("%d\n",ans);
            s[id - 1] = t[0];
        }
    
    }   
    int main() {
        // int _;
        // for(scanf("%d",&_);_;_--) {
            solve();
        //}
      //  system("pause");
        return 0;
    }
    View Code

    C:倒着dp即可,用e来判断

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const int N = 2e5 + 5;
    const int M = 1e6 + 5;
    const LL Mod = 1e9 + 7;
    #define rep(at,am,as) for(int at = am;at <= as;++at)
    #define ret(at,am,as) for(int at = am;at >= as;--at)
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline long long ADD(long long x,long long y) {
        if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
        return (x + y) % Mod;
    }
    inline long long MUL(long long x,long long y) {
        if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
        return x * y % Mod;
    }
    inline long long DEC(long long x,long long y) {
        if(x - y < 0) return (x - y + Mod) % Mod;
        return (x - y) % Mod;
    }
    
    int n,e,a[M];
    bool vis[M];
    int prime[M],tot = 0;
    void init() {
        for(int i = 2;i < M;++i) {
            if(!vis[i]) prime[++tot] = i;
            for(int j = 1;j <= tot && prime[j] * i < M;++j) {
                vis[prime[j] * i] = 1;
                if(i % prime[j] == 0) break;
            }
        }
    }
    int dp[M],cnt[M];//0 - not 1
    void solve() {
        scanf("%d %d",&n,&e);
        for(int i = 1;i <= n;++i) scanf("%d",&a[i]);
        for(int i = 1;i <= (n + e + 5);++i) dp[i] = cnt[i] = 0;
        LL ans = 0;
        ret(i,n,1) {
            cnt[i] = cnt[i + e] + 1;
            if(a[i] == 1) {
                dp[i] = dp[i + e];
                if(dp[i] != 0) {
                    if(vis[a[dp[i]]]) continue;
                    if(dp[dp[i] + e] == 0 || dp[i] + e > n) ans += cnt[dp[i]];
                    else {
                        ans += cnt[dp[i]] - cnt[dp[dp[i] + e]];
                    }
                }
            }
            else {
                if(!vis[a[i]]) {
                    if(i + e <= n) {
                        if(dp[i + e] == 0) ans += cnt[i + e];
                        else {
                            ans += cnt[i] - cnt[dp[i + e]] - 1;
                        }
                    }
                }
                dp[i] = i;
            }
        }
        printf("%lld\n",ans);
    
    }   
    int main() {
        init();
        int _;
        for(scanf("%d",&_);_;_--) {
            solve();
        }
       // system("pause");
        return 0;
    }
    View Code

    D:什么逆天题意。

    多的边直接连其他连通块即可。

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const int N = 1e3 + 5;
    const int M = 1e6 + 5;
    const LL Mod = 1e9 + 7;
    #define rep(at,am,as) for(int at = am;at <= as;++at)
    #define ret(at,am,as) for(int at = am;at >= as;--at)
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline long long ADD(long long x,long long y) {
        if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
        return (x + y) % Mod;
    }
    inline long long MUL(long long x,long long y) {
        if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
        return x * y % Mod;
    }
    inline long long DEC(long long x,long long y) {
        if(x - y < 0) return (x - y + Mod) % Mod;
        return (x - y) % Mod;
    }
    
    int fa[N],ans[N],sz[N];
    int Find(int x) {return x == fa[x] ? x : fa[x] = Find(fa[x]);}
    bool vis[N][N];
    void solve() {
        int n,d;scanf("%d %d",&n,&d);
        for(int i = 1;i <= n;++i) fa[i] = i,sz[i] = 1;
        int cnt = 0;
        while(d--) {
            int ans = 0;
            int x,y;scanf("%d %d",&x,&y);
            int xx = Find(x),yy = Find(y);
            vector<int> vec;
            if(xx != yy) {
                fa[xx] = yy,sz[yy] += sz[xx];
            }
            else cnt++;
            rep(i,1,n) if(i == Find(i)) vec.push_back(sz[i]);
            sort(vec.begin(),vec.end(),greater<int>());
            rep(i,1,min((int)vec.size(),cnt + 1)) ans += vec[i - 1]; 
            printf("%d\n",ans - 1);
        }
    
    }   
    int main() {
        //int _;
        //for(scanf("%d",&_);_;_--) {
            solve();
        //}
        //system("pause");
        return 0;
    }
    View Code

    E:这题还是挺不错的。

    线段树上维护一个dp。

    首先我们考虑一下状压一下状态,第0位代表a,第1位代表b,第2位代表c,第3位代表ab,第4位代表bc。

    dp[i] - 表示序列中只包含状态i的情况。

    首先问题就是为什么只有这几种情况,因为只有他们对答案有影响,其他的都可以当场什么状态都没的情况即0。

    然后就是两个序列合并之后产生的情况,需要充分考虑,然后对于ab这种,其实a和b状态必定包含在里面,所以必须要算上。

    合并的时候就是dp[i][j] = min{dp[i][k] + dp[k][j]},类似Floyd。

    有点像DFA上的Floyd.

    // Author: levil
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef long double ld;
    typedef pair<int,int> pii;
    const int N = 1e5 + 5;
    const int M = 1e6 + 5;
    const LL Mod = 1e9 + 7;
    #define rep(at,am,as) for(int at = am;at <= as;++at)
    #define ret(at,am,as) for(int at = am;at >= as;--at)
    #define INF 1e9
    #define dbg(ax) cout << "now this num is " << ax << endl;
    inline long long ADD(long long x,long long y) {
        if(x + y < 0) return ((x + y) % Mod + Mod) % Mod;
        return (x + y) % Mod;
    }
    inline long long MUL(long long x,long long y) {
        if(x * y < 0) return ((x * y) % Mod + Mod) % Mod;
        return x * y % Mod;
    }
    inline long long DEC(long long x,long long y) {
        if(x - y < 0) return (x - y + Mod) % Mod;
        return (x - y) % Mod;
    }
    
    int n,q;
    char s[N];
    struct Node{int L,r,dp[1 << 5];}node[N << 2];//0 - a,1 - b,2 - c,3 - ab,4 - bc
    int Merge[1 << 5][1 << 5];
    bool ishav(int i,int k) {
        if((i >> k) & 1) return true;
        else return false;
    }
    bool judge(int i,int j) {
        if(ishav(i,0) && ishav(j,4)) return false;
        if(ishav(i,3) && (ishav(j,4) || ishav(j,2))) return false;
        return true;
    }
    void init() {
        rep(i,0,(1 << 5) - 1) {
            rep(j,0,(1 << 5) - 1) {
                if(!judge(i,j)) Merge[i][j] = -1;
                else {
                    rep(k,0,4) if(ishav(i,k) || ishav(j,k)) Merge[i][j] |= (1 << k);
                    if(ishav(i,0) && ishav(j,1)) Merge[i][j] |= (1 << 3);
                    if(ishav(i,1) && ishav(j,2)) Merge[i][j] |= (1 << 4);
                    if(ishav(i,3) || ishav(j,3)) Merge[i][j] |= (1 << 0),Merge[i][j] |= (1 << 1);
                    if(ishav(i,4) || ishav(j,4)) Merge[i][j] |= (1 << 1),Merge[i][j] |= (1 << 2);
                }
            }
        }
        // rep(i,0,(1 << 5) - 1) {
        //     rep(j,0,(1 << 5) - 1) {
        //         printf("mask[%d][%d] is %d\n",i,j,Merge[i][j]);
        //     } 
        // }
    }
    void Pushup(int idx) {
        int ls = idx << 1,rs = idx << 1 | 1;
        rep(i,0,(1 << 5) - 1) node[idx].dp[i] = INF;
        rep(i,0,(1 << 5) - 1) {
            rep(j,0,(1 << 5) - 1) {
                if(Merge[i][j] == -1) continue;
                node[idx].dp[Merge[i][j]] = min(node[idx].dp[Merge[i][j]],node[ls].dp[i] + node[rs].dp[j]);
            }
        }
    }
    void build(int L,int r,int idx) {
        node[idx].L = L,node[idx].r = r;
        rep(i,0,(1 << 5) - 1) node[idx].dp[i] = INF;
        if(L == r) {
            int val = s[L -1] - 'a';
            node[idx].dp[1 << val] = 0;
            node[idx].dp[0] = 1;
            return ;
        }
        int mid = (L + r) >> 1;
        build(L,mid,idx << 1);
        build(mid + 1,r,idx << 1 | 1);
        Pushup(idx);
    }
    void modify(int x,char c,int idx) {
        if(node[idx].L == node[idx].r) {
            rep(i,0,(1 << 5) - 1) node[idx].dp[i] = INF;
            int val = c - 'a';
            node[idx].dp[1 << val] = 0;
            node[idx].dp[0] = 1; 
            return ;
        }
        int mid = (node[idx].L + node[idx].r) >> 1;
        if(mid >= x) modify(x,c,idx << 1);
        else modify(x,c,idx << 1 | 1); 
        Pushup(idx);
    }
    void solve() {
        init();
        scanf("%d %d",&n,&q);
        scanf("%s",s);
        build(1,n,1);
        while(q--) {
            int x;char c;
            scanf("%d",&x);getchar();
            c = getchar();
            if(s[x - 1] != c) modify(x,c,1),s[x - 1] = c;
            int ans = INF;
            rep(i,0,(1 << 5) - 1) ans = min(ans,node[1].dp[i]);
            printf("%d\n",ans);
        }
    }   
    int main() {
        //int _;
        //for(scanf("%d",&_);_;_--) {
            solve();
        //}
        system("pause");
        return 0;
    }
    View Code
  • 相关阅读:
    HDU 3572 Task Schedule(拆点+最大流dinic)
    POJ 1236 Network of Schools(Tarjan缩点)
    HDU 3605 Escape(状压+最大流)
    HDU 1166 敌兵布阵(分块)
    Leetcode 223 Rectangle Area
    Leetcode 219 Contains Duplicate II STL
    Leetcode 36 Valid Sudoku
    Leetcode 88 Merge Sorted Array STL
    Leetcode 160 Intersection of Two Linked Lists 单向链表
    Leetcode 111 Minimum Depth of Binary Tree 二叉树
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/15631054.html
Copyright © 2020-2023  润新知