Contest 9

  A:搜索好难啊根本不会啊。

  B:暴力枚举给哪段前缀乘,维护一些前后缀最大最小值之类的东西就很好算了。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
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<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
#define N 1000010
#define ll long long
int n,w,v,a[N];
ll ans=-10000000000000000,sum[N],pre[N],suf[N];
int main()
{
    freopen("game.in","r",stdin);
    freopen("game.out","w",stdout);
    n=read(),w=-read(),v=-read();
    for (int i=1;i<=n;i++) a[i]=read();
    for (int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
    for (int i=1;i<=n+1;i++) pre[i-1]=suf[i]=(sum[n]-sum[i-1])*v+sum[i-1];
    for (int i=1;i<=n;i++) pre[i]=max(pre[i],pre[i-1]);
    for (int i=n;i;i--) suf[i]=min(suf[i],suf[i+1]);
    for (int i=0;i<=n;i++)
    ans=max(ans,min(sum[i]*w+suf[i+1]-sum[i],(sum[n]-sum[i])*v+(pre[i]-(sum[n]-sum[i])*v)*w));
    cout<<ans;
    return 0;
}
View Code

  C:吐槽一下这场的心路历程。开场看A,看了一会性质发现转化成了一个2-SAT,这玩意怎么还能计数啊?盯了一个小时一点都不会,暴力都没写就跑了。心态从这就开始崩了。然后半个小时搞掉B。C开始胡乱分析一下觉得某结论很显然,然后写了一个小时差不多搞定了,结果因为各种写挂,大样例跑的比答案大。然而并没有冷静下来去验证结论,并且由于数据范围才50觉得自己肯定假掉了,于是开始退火。退了半天总是比答案小,到处找锅没有任何收获,最后弃疗了连交都没交了。之后调了两个小时才发现做mst时边权开的是int于是炸成负数了。

  这个题胡乱分析一下性质跑mst就好了。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<ctime>
using namespace std;
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<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
#define N 55
#define T1 1e5
#define T2 1e-8
#define delta 0.98
int n,a[N][N],b[N][N],id[N],id2[N],dfn[N],fa[N],c;
long long t[N],u[N],f[N],tmp[N],dis[N][N],ans,tot=1000000000000000;
bool cmp(const int&a,const int&b)
{
    return f[a]>f[b];
}
struct data
{
    int x,y;long long z;
    bool operator <(const data&a) const
    {
        return z<a.z;
    }
}edge[N*N];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void SWAP(int x,int y)
{
    swap(id[x],id[y]);
    dfn[id[x]]=x,dfn[id[y]]=y;
}
long long getans()
{
    ans=0;
    for (int i=1;i<=n;i++) fa[i]=i;
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
        if (a[i][j]) fa[find(i)]=find(j);
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=n;j++)
        if (a[i][j])
            if (dfn[j]<dfn[i]) ans+=u[j]*f[i]*(u[i]-t[i]);
            else if (dfn[j]>dfn[i]) ans+=t[j]*f[i]*(u[i]-t[i]);
        ans+=f[i]*((u[i]-1)+t[i])*(u[i]-t[i])>>1;
    }
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
        dis[i][j]=100000000000000000;
    for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
        if (dfn[i]<dfn[j])
        {
            int p=find(i),q=find(j);
            if (p!=q) dis[p][q]=min(dis[p][q],(t[i]+t[j])*c+t[j]*f[i]*(u[i]-t[i])+u[i]*f[j]*(u[j]-t[j]));
        }
    int cnt=0;memset(id2,0,sizeof(id2));
    for (int i=1;i<=n;i++) if (find(i)==i) id2[++cnt]=i;
    int num=0;
    for (int i=1;i<=cnt;i++)
        for (int j=1;j<=cnt;j++)
        num++,edge[num].x=id2[i],edge[num].y=id2[j],edge[num].z=dis[id2[i]][id2[j]];
    sort(edge+1,edge+num+1);
    for (int i=1;i<=n;i++) fa[i]=i;
    for (int i=1;i<=num;i++)
    if (find(edge[i].x)!=find(edge[i].y)) ans+=edge[i].z,fa[find(edge[i].x)]=edge[i].y;
    return ans;
}
void solve()
{
    double T=T1;
    long long lastans=tot;
    while (T>T2)
    {
        int x=rand()%(n-1)+1,y=rand()%(n-x)+x+1;
        SWAP(x,y);
        ans=getans();
        if (ans<lastans||exp((lastans-ans)/T)>1.0*rand()/RAND_MAX) tot=min(tot,ans);
        else SWAP(x,y),ans=lastans;
        T*=delta;lastans=ans;
    }
}
int main()
{
    freopen("reconstruction.in","r",stdin);
    freopen("reconstruction.out","w",stdout);
    n=read();srand(time(0));
    for (int i=1;i<=n;i++) t[i]=read();
    for (int i=1;i<=n;i++) u[i]=read();
    for (int i=1;i<=n;i++) f[i]=read();
    if (n==1) {cout<<(f[1]*((u[1]-1)+t[1])*(u[1]-t[1])>>1);return 0;}
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=n;j++)
        {
            char c=getchar();
            while (c!='Y'&&c!='N') c=getchar();
            if (c=='Y') a[i][j]=1;
        }
    }
    c=read();
    for (int i=1;i<=n;i++) id[i]=i;
    sort(id+1,id+n+1,cmp);
    for (int i=1;i<=n;i++) dfn[id[i]]=i;
    tot=getans();
    //solve();
    cout<<tot;
    return 0;
}
View Code

  result:- rank-

原文地址:https://www.cnblogs.com/Gloid/p/9748121.html