zoukankan      html  css  js  c++  java
  • 8.14 Round 1

    心态爆炸——

    T2小细节出大锅,T3没写%lld,75pts->15pts

    T1:https://www.luogu.org/problem/T94043

    MST,USACO有原题

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<climits>
    #include<map>
    #include<queue>
    #include<cmath>
    using namespace std;
    #define O(x) cout << #x << " " << x << endl;
    #define B cout << "breakpoint" << endl;
    #define clr(a) memset(a,0,sizeof(a));
    typedef long long ll;
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    const int maxm = 2e6 + 5; 
    const int maxn = 1006;    
    struct egde
    {
        int u,v,w;
        bool operator < (const egde& b) const
        {
            return  w < b.w;
        }
    }e[maxm];
    struct node
    {
        int x,y;
    }a[maxn];
    int tot;
    int n,A,b;
    void adde(int u,int v,int w) { e[++tot].u = u; e[tot].v = v,e[tot].w = w; }
    int par[maxn],rk[maxn];
    void init() { for(int i = 1;i <= maxn - 5;i++) par[i] = i; }
    inline int find(int x) { return x == par[x] ? x : par[x] = find(par[x]); }
    inline void merge(int x,int y)
    {
        x = find(x); y = find(y);
        if(x == y) return;
        if(rk[x] < rk[y]) par[x] = y;
        else par[y] = x;
        if(rk[x] == rk[y]) rk[x]++;
    }
    int cnt;
    ll ans;
    void kruskal()
    {
        sort(e + 1,e + 1 + tot);
        for(int i = 1;i <= tot;i++)
        {
            int u = find(e[i].u),v = find(e[i].v);
            if(u == v) continue;
            merge(u,v); ans = ans + 1ll * e[i].w; cnt++;
            if(cnt == n) break;
        }
    }
    int main()
    {
        freopen("pupil.in","r",stdin);
        freopen("pupil.out","w",stdout);
        init();
        n = read(),A = read(),b = read();
        for(int i = 1;i <= n;i++) 
        {
            adde(i,n + 1,A);
            a[i].x = read(),a[i].y = read();
            for(int j = 1;j < i;j++)
                {
                    int d = abs(a[i].x - a[j].x) + abs(a[i].y - a[j].y);
                    adde(i,j,d * b);
                }
        }
        kruskal();
        printf("%lld",ans);
    }
    View Code

    T2:https://www.luogu.org/problem/T94044

    线段覆盖,细节出锅

    pos在排序前后对应的线段肯定改变了,没注意到,直接GG

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<climits>
    #include<map>
    #include<queue>
    #include<cmath>
    using namespace std;
    #define clr(a) memset(a,0,sizeof(a));
    typedef long long ll;
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    const int maxn = 5e5 + 5;
    struct node
    {
        int l,r,id;
        bool operator < (const node& b) const
        {
            if(l == b.l) return r > b.r;
            return l < b.l;
        }
    }a[maxn];
    int n,pos,ans = 1;
    int main()
    {
        freopen("cat.in","r",stdin);
        freopen("cat.out","w",stdout);
        n = read();
        for(int i = 1;i <= n;i++)
        {
            int x = read();
            a[i].l = i - x,a[i].r = i + x,a[i].id = i;
            if(a[i].l <= 1 && a[i].r > a[pos].r) pos = i;
        }
        sort(a + 1,a + 1 + n);
        /*for(int i = 1;i <= n;i++)
        printf("%d %d %d
    ",a[i].l,a[i].r,a[i].id); */
        for(int i = 1;i <= n;i++) if(a[i].id == pos) { pos = i; break; }
        int i = pos + 1;
        while(i <= n)
        {
            //O(a[i].r); //O(a[pos].r);
            int tpos = 0;
            while(a[i].l <= a[pos].r + 1 && i <= n) 
            {
                if(a[i].r > a[tpos].r) tpos = i;
                i++;
            }
            pos = tpos,ans++;
            if(a[pos].r >= n) break;
        }
        printf("%d",ans);
    }
    /*
    10
    0 0 0 0 0 0 0 0 0 0 */
    View Code

    T3:https://www.luogu.org/problem/T94046

    斜率优化,70pts做法

    100pts就在优化的时候把dp数组带上

    输出long long的时候一定要用%lld!!!!!不论是否超int

    不然在有的评测环境下只有0

    75pts:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<climits>
    #include<map>
    #include<queue>
    #include<cmath>
    using namespace std;
    #define clr(a) memset(a,0,sizeof(a));
    #define int long long
    typedef long long ll;
    typedef double db;
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    const int maxn = 1e6 + 5;
    int sum[maxn],d[maxn],a1[maxn],a2[maxn];
    int n,k;
    int totans;
    int q[maxn],head,tail,f[maxn];
    db get_k(int j,int k) {return (sum[j] * d[j] - sum[k] * d[k]) / (sum[j] - sum[k]); } 
    main()
    {
        freopen("life.in","r",stdin);
        freopen("life.out","w",stdout);
        n = read(),k = read();
        for(int i = 1;i <= n;i++)
        {
            a1[i] = read(),a2[i] = read();
            sum[i] = sum[i - 1] + a1[i];
        }
        for(int i = n;i >= 1;i--) d[i] = d[i + 1] + a2[i];
        for(int i = 1;i <= n;i++)
            totans += a1[i] * d[i];
        if(k == 0) { printf("%lld
    ",totans); return 0; }
        if(k == 1)
        {
            int ans = LONG_LONG_MAX,pos = 0;
            for(int i = 1;i <= n;i++)
            {
                int res = totans - sum[i] * d[i];
                if(ans > res) ans = res,pos = i;
            }
            printf("%lld
    ",ans);
            printf("%lld ",pos - 1);
            return 0; 
        } 
        if(k == 2)
        {
            int ans = LONG_LONG_MAX;
            int p1,p2;
                for(int i = 1;i <= n;i++)
                {
                    while(head < tail)
                    {
                        if(get_k(q[head],q[head + 1]) > d[i]) head++;
                        else break;
                    } 
                    while(tail > head)
                    {
                        if(get_k(i,q[tail]) > get_k(q[tail],q[tail - 1])) tail--;
                        else break;
                    }
                    q[++tail] = i;
                    int j = q[head];
                    int res = totans - d[i] * (sum[i] - sum[j]) - d[j] * sum[j];
                    if(ans > res) ans = res,p1 = j,p2 = i;
                }
                //if(p1 > p2) swap(p1,p2);
                printf("%lld
    ",ans);
                printf("%lld %lld ",p1 - 1,p2 - 1);
                puts("");
                return 0;
        }
        if(k == 3)
        {
            int ans = LONG_LONG_MAX;
            int p1,p2,p3;
            for(int i = 1;i <= n;i++)
                for(int j = i + 1;j <= n;j++)
                    for(int k = j + 1;k <= n;k++)
                    {
                        int res = totans - d[i] * sum[i] - d[j] * (sum[j] - sum[i]) - d[k] * (sum[k] - sum[j]);
                        if(ans > res) ans = res,p1 = i,p2 = j,p3 = k;
                    }
            printf("%lld
    ",ans);
            printf("%lld %lld %lld ",p1 - 1,p2 - 1,p3 - 1);
            return 0;
        }
    }
    /*
    4 3
    1 1
    2 2
    3 3
    4 4
    */
                
        
    View Code

    AC:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<climits>
    #include<map>
    #include<queue>
    #include<cmath>
    using namespace std;
    #define clr(a) memset(a,0,sizeof(a));
    #define int long long
    typedef long long ll;
    typedef double db;
    inline int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
            if(ch == '-') op = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
            (ans *= 10) += ch - '0';
            ch = getchar();
        }
        return ans * op;
    }
    const int maxn = 1e6 + 5;
    int sd[maxn],sw[maxn],a1[maxn],a2[maxn],S[maxn],d[maxn],w[maxn];
    int n,k;
    int totans;
    int q[maxn],head,tail,f[maxn][21],pos[maxn][21],ans[maxn];
    db get_k(int x,int y,int k) 
    { 
        db Y = f[x][k - 1] - f[y][k - 1] + S[x] - S[y],X = sw[x] - sw[y];
        return Y / X; 
    } 
    main()
    {
        freopen("life.in","r",stdin);
        freopen("life.out","w",stdout);
        n = read(),k = read();
        for(int i = 1;i <= n;i++)
        {
            w[i] = read(),d[i] = read();
            sw[i] = sw[i - 1] + w[i];
            sd[i] = sd[i - 1] + d[i - 1];
            S[i] = S[i - 1] + sd[i] * w[i];
        }
        sd[n + 1] = sd[n] + d[n]; sw[n + 1] = sw[n],S[n + 1] = S[n];
        memset(f,0x3f,sizeof(f));
        f[0][0] = 0;
        for(int j = 1;j <= k + 1;j++)
        {
        for(int i = 1;i <= n + 1;i++)
        {
            while(head < tail)
            {
                if(get_k(q[head + 1],q[head],j) <= sd[i]) head++;
                else break;
            } 
            while(tail > head)
            {
                if(get_k(i,q[tail],j) <= get_k(q[tail],q[tail - 1],j)) tail--;
                else break;    
            }
            q[++tail] = i;
            int t = q[head];
            pos[i][j] = t;
            f[i][j] = f[t][j - 1] - sd[i] * sw[t] + S[t] + sd[i] * sw[i] - S[i];
        }
        head = tail = 0;
        }
        printf("%lld
    ",f[n + 1][k + 1]);
        int now = n+1,tt = k+1;
        while(now)
        {
            ans[++ans[0]] = pos[now][tt];
            now = ans[ans[0]],tt--;
        }
        for(int i = ans[0]-1;i>=1;--i)printf("%lld ",ans[i]-1);
    }
    /*
    4 3
    1 1
    2 2
    3 3
    4 4
    */
                
        
    View Code
  • 相关阅读:
    maven插件安装与使用
    java面试题
    关于java的GC
    技术人员要树立自己的品牌
    为什么IT公司都应该鼓励开源
    你应该坚持写博客 即使没有读者
    计算机基础
    收藏 | 产品经理不可不知的 7 种技术思维
    我讨厌你公事公办的样子
    子序列问题【LIS、LCS、LCIS】
  • 原文地址:https://www.cnblogs.com/LM-LBG/p/11351986.html
Copyright © 2011-2022 走看看