zoukankan      html  css  js  c++  java
  • 《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
  • 相关阅读:
    Java多线程——volatile关键字、发布和逸出
    线程安全性的基础知识
    maven web不能创建src/main/java等文件等问题
    web环境中的spring MVC
    Spring AOP 概述
    golang统计出其中英文字母、空格、数字和其它字符的个数
    go语言求1到100之内的质数
    golang fmt占位符
    golang---map类型
    golang切片类型
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/15631054.html
Copyright © 2011-2022 走看看