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\n",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\n",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\n",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\n",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\n",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\n",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

 

posted on 2019-08-14 15:03  L_M_A  阅读(136)  评论(0编辑  收藏  举报

导航