zoukankan      html  css  js  c++  java
  • codeforces-1140 (div2)

    A.维护一个前缀最大值,不断跳即可

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++)  
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x);  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x);  
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();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;}
    const double eps = 1e-9;
    const int maxn = 1e4 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,K;
    int a[maxn];
    int Max[maxn];
    int main(){
        Sca(N);
        for(int i = 1; i <= N ; i ++){
            Sca(a[i]);
            a[i] = max(a[i],a[i - 1]);
        }
        int cnt = 0;
        int now = 0;
        while(now < N){
            cnt++;
            now++;
            while(now != a[now]) now = a[now];
        }
        Pri(cnt);
        return 0;
    }
    A

    B.从左边开始删除一直删到>或者从右边开始删除一直删到<,两种方案取最小值。

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++)  
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x);  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x);  
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();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;}
    const double eps = 1e-9;
    const int maxn = 110;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,K;
    char str[maxn];
    int main(){
        int T = read();
        while(T--){
            Sca(N);
            scanf("%s",str + 1);
            int ans = N - 1;
            for(int i = 1; i <= N ; i ++){
                if(str[i] == '>'){
                    ans = min(ans,i - 1);
                    break;
                }
            }
            for(int i = N ; i >= 1; i --){
                if(str[i] == '<'){
                    ans = min(ans,N - i);
                    break;
                }
            }
            Pri(ans);
        }
        return 0;
    }
    B

    C.按照beauty值从大到小排序,维护一个前缀和(最多K个length),小根堆维护一下每次要踢出哪个最小lenght的弟弟

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++)  
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x);  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x);  
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();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;}
    const double eps = 1e-9;
    const int maxn = 3e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,K;
    PLL P[maxn];
    bool cmp(PLL a,PLL b){
        return a.se > b.se;
    }
    int main(){
        Sca2(N,K);
        for(int i = 1; i <= N; i ++){
            scanf("%lld%lld",&P[i].fi,&P[i].se);
        }
        sort(P + 1,P + 1 + N,cmp);
        priority_queue<LL,vector<LL>,greater<LL>>Q;
        LL sum = 0;
        LL ans = 0;
        for(int i = 1; i <= N ; i ++){
            ans = max(ans,(sum + P[i].fi) * P[i].se);
            Q.push(P[i].fi); sum += P[i].fi;
            if(Q.size() >= K){
                sum -= Q.top();
                Q.pop();
            } 
        }
        Prl(ans);
        return 0;
    }
    C

    D.发现1,2,3| 1,3,4| 1,4,5 .. |1,n - 1,n为最优解。

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++)  
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x);  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x);  
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();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;}
    const double eps = 1e-9;
    const int maxn = 3e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,K;
    
    int main(){
        Sca(N);
        LL sum = 0;
        for(int i = 2; i < N ; i ++){
            sum += i * (i + 1);
        }
        Prl(sum);
        return 0;
    }
    D

    E*

    1.发现不存在奇长度的回文串只需要满足不存在长度3的回文串即可,长度为5的回文串包含了长度3的回文串。

    2.也就是说,要满足所有的str[x] != str[x + 2],发现奇偶位置上的数字其实互不干扰,那可以把序列分成两个序列来做。

    3.得到dp方程,dp[i][j]表示到了i这个位置,且这个位置上的数字为j的时候,满足条件序列的总数,状态转移方程为dp[i][j] = ∑dp[i - 1][p] (1 <= p <= K && p != j)

    4.当然这个时间复杂度和空间复杂度双双nk的算法是行不通的,我们发现对于i相同的dp[i][j],只会有两种不同的值,并且是其中k - 1个值相同以及另一个值鹤立鸡群的情况(当然也有可能都是鸡完全相同)

    5.考虑标注特殊的点位置和特殊的点值以及k - 1个其他的点值,即可压缩复杂度为O(n)

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++)  
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x);  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x);  
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();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;}
    const double eps = 1e-9;
    const int maxn = 2e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 998244353; 
    int N,M,K;
    LL a[maxn],b[maxn];
    LL solve(LL *x,int n){
        LL big,small,pos;
        if(x[1] == -1){
            big = 1; small = 1; pos = 1;
        }else{
            big = 0; small = 1; pos = x[1];
        } 
        for(int i = 2; i <= n ; i ++){
            if(x[i] == -1){
                LL s = big * (K - 1),b = big * (K - 2)  + small;
                small = s % mod; big = b % mod;
            }else{
                if(pos == x[i]){
                    small = big * (K - 1) % mod;
                    big = 0;
                }else{
                    small = big * (K - 2) + small; small %= mod;
                    pos = x[i];
                    big = 0;
                }
            }
        }
        return (small + big * (K - 1)) % mod;
    }
    int main(){
        Sca2(N,K);
        int cnt1 = 0,cnt2 = 0;
        for(int i = 1; i <= N ; i ++){
            if(i & 1) a[++cnt1] = read();
            else b[++cnt2] = read();
        }
        Prl(solve(a,cnt1) * solve(b,cnt2) % mod);
        return 0;
    }
    E

    F*

    1.考虑将两个集合用一个二维的表来表示,添加就是将i行j列合并,最终答案是每个联通块的行数 * 列数。

    2.考虑到用并查集,size1[maxn],size2[maxn],分别表示这个集合里面行列的数量。

    3.问题在于删除,并查集是不存在在线直接删除这种黑科技的,但是我们可以用离线的方式,将并查集的存在生命周期放到线段树上,然后dfs整颗线段树进行优化。

    这个操作在BZOJ2049里遇到过了,当时还写了blog https://www.cnblogs.com/Hugh-Locke/p/10367480.html

    结果这次还是翻皮水了(雾)

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++)  
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x);  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x);  
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();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;}
    const double eps = 1e-9;
    const int maxn = 6e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,K;
    map<PII,int>P;
    //并查集 
    int fa[maxn];
    LL size1[maxn],size2[maxn];
    int dep[maxn];
    void init(){
        for(int i = 0; i < maxn; i ++){
            fa[i] = i;
            if(i > 3e5) size2[i] = 1;
            else size1[i] = 1;
            dep[i] = 0;
        } 
    }
    //线段树
    struct Edge{
        PII to;
        int next;
    }edge[maxn * 20];
    int tot;
    void add(int& t,PII w){
        edge[tot].to = w;
        edge[tot].next = t;
        t = tot++;
    }
    struct Tree{
        int l,r;
        int head;
    }tree[maxn << 2]; 
    void Build(int t,int l,int r){
        tree[t].l = l; tree[t].r = r;
        tree[t].head = -1;
        if(l == r) return;
        int m = l + r >> 1;
        Build(t << 1,l,m); Build(t << 1 | 1,m + 1,r);
    }
    void add(int t,int l,int r,PII w){
        if(l <= tree[t].l && tree[t].r <= r){
            add(tree[t].head,w);
            return;
        }
        int m = tree[t].l + tree[t].r >> 1;
        if(r <= m) add(t << 1,l,r,w);
        else if(l > m) add(t << 1 | 1,l,r,w);
        else{
            add(t << 1,l,m,w); add(t << 1 | 1,m + 1,r,w);
        }
    }
    int Stack[maxn],top;
    int find(int x){
        while(fa[x] != x) x = fa[x];
        return x;
    }
    LL ans; 
    void rewind(int t){
        while(top > t){
             int x = Stack[--top];
             dep[fa[x]] -= dep[x] + 1;
             ans -= 1LL * size1[fa[x]] * size2[fa[x]];
             size1[fa[x]] -= size1[x];
             size2[fa[x]] -= size2[x];
             ans += 1LL * size1[fa[x]] * size2[fa[x]];
             ans += 1LL * size1[x] * size2[x];
             fa[x] = x;
        }
    }
    void dfs(int t){
        int now = top;
        for(int i = tree[t].head; ~i ; i = edge[i].next){
            PII t = edge[i].to;
            t.fi = find(t.fi); t.se = find(t.se);
            if(t.fi == t.se) continue;
            if(dep[t.fi] > dep[t.se]) swap(t.fi,t.se);
            Stack[top++] = t.fi;
            fa[t.fi] = t.se;
            dep[t.se] += dep[t.fi] + 1;
            ans -= 1LL * size1[t.fi] * size2[t.fi]; ans -= size1[t.se] * size2[t.se];
            size1[t.se] += size1[t.fi]; size2[t.se] += size2[t.fi];
            ans += 1LL * size1[t.se] * size2[t.se];
        }
        if(tree[t].l == tree[t].r){
            printf("%lld ",ans);
        }else{
            dfs(t << 1); 
            dfs(t << 1 | 1);
        }
        rewind(now);
    }
    int main(){
        Sca(N); init();
        Build(1,1,N);
        for(int i = 1; i <= N; i ++){
            PII p; p.fi = read(),p.se = read() + 3e5;
            if(P[p]){
                add(1,P[p],i - 1,p);
                P[p] = 0;
            }else P[p] = i;
        }
        for(map<PII,int>::iterator it = P.begin(); it != P.end(); it++)  if((*it).se) add(1,(*it).se,N,(*it).fi);
        dfs(1);
        return 0;
    }
    F
  • 相关阅读:
    PHP时间戳常用转换
    redis基本指令
    P2501 [HAOI2006]数字序列
    P2679 子串
    P2759 奇怪的函数
    P6823 「EZEC-4」zrmpaul Loves Array
    P6631 [ZJOI2020] 序列
    P2887 [USACO07NOV]Sunscreen G
    P3287 [SCOI2014]方伯伯的玉米田
    拓展欧几里得算法揭秘
  • 原文地址:https://www.cnblogs.com/Hugh-Locke/p/10667769.html
Copyright © 2011-2022 走看看