2017-4-7校内训练

Posted ditoly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2017-4-7校内训练相关的知识,希望对你有一定的参考价值。

丧病hzwer的ctsc训练赛 My AC:3/4

 

A.[Ctsc2014]企鹅QQ

思路:乱hash,我比较菜,写的丑代码各种WA+TLE,好久才A掉。

#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
#define MN 200
#define MX 6000000
#define MM 9000001
#define MOD1 890123798112473LL
struct map
{
    struct edge{int nx,t;ll x;}e[MX+5];
    int h[MM],en;
    inline int&operator[](ll x)
    {
        int p=(x%MM+MM)%MM;
        for(int i=h[p];i;i=e[i].nx)if(e[i].x==x)return e[i].t;
        e[++en]=(edge){h[p],0,x};h[p]=en;
        return e[en].t;
    }
}mp1,mp2;
char s[MN+5];
ll f1[MN+5],f2[MN+5];
int main()
{
    int n,m,k,i,ans=0;ll h1,h2;
    scanf("%d%d%d",&n,&m,&k);
    while(n--)
    {
        scanf("%s",s+1);
        for(i=m;i;--i)f1[i]=(f1[i+1]*31^(s[i]+23))%MOD1,
                      f2[i]=(f2[i+1]*37^(s[i]+23));
        for(i=1,h1=h2=0;i<=m;++i)
        {
            ans+=min(mp1[h1*23333^f1[i+1]]++,mp2[h2*23333^f2[i+1]]++);
            h1=(h1*37+s[i])%MOD1;h2=(h2*31+s[i]);
        }
    }
    printf("%d",ans);
}

 

B.[CTSC2007]数据备份Backup

思路:显然只有相邻的会被选,先把所有相邻线段用链表链起来塞到堆里,每次取出最小的,与他相邻的线段暂时不能选就删掉,如果要在之后再选相邻的这两条,显然不可能只选其中一条而不选中间这条,我们把这三条合并成左+右-中再塞回堆即可。

#include<cstdio>
#include<queue>
using namespace std;
inline int read()
{
    int x;char c;
    while((c=getchar())<0||c>9);
    for(x=c-0;(c=getchar())>=0&&c<=9;)x=(x<<3)+(x<<1)+c-0;
    return x;
}
#define MN 100000
int a[MN+5],l[MN+5],r[MN+5],w[MN+5],u[MN+5];
class cmp{public:bool operator()(int a,int b){return w[a]>w[b];}};
priority_queue<int,vector<int>,cmp> pq;
int main()
{
    int n,k,i,x,ans=0;
    n=read();k=read();
    for(i=1;i<=n;++i)a[i]=read();
    w[0]=w[n]=1e9;
    for(i=1;i<n;++i)l[i]=i-1,r[i]=i+1,w[i]=a[i+1]-a[i],pq.push(i);
    for(i=0;i<k;++i)
    {
        do x=pq.top(),pq.pop();while(u[x]);
        ans+=w[x];
        w[x]=w[l[x]]+w[r[x]]-w[x];
        u[l[x]]=u[r[x]]=1;
        l[x]=l[l[x]];r[x]=r[r[x]];
        pq.push(r[l[x]]=l[r[x]]=x);
    }
    printf("%d",ans);
}

 

C.[Ctsc2015]misc

思路:枚举s,每个s先跑一遍单源最短路,只考虑最短路上的边(即满足dis[u]+len=dis[v]的边),得到一张拓扑图,在拓扑图上先dp出s到每个点的最短路宽度$\sigma_{st}$

考虑每个v,$R(v)=\sum \frac{a_{s}a_{t}\sigma_{st}(v)}{\sigma{st}}=\sum \frac{a_{s}a_{t}\sigma_{sv}\sigma_{vt}}{\sigma{st}}=a_{s}\sigma_{sv}\sum\frac{a_{t}\sigma_{vt}}{\sigma_{st}}$,其中t为v在最短路拓扑图中能到的点。

我们令$f(v)=\sum\frac{a_{t}\sigma_{vt}}{\sigma_{st}}$,则有$f(u)=\sum c_{j}(\frac{a_{v}}{\sigma_{sv}}+f(v))$,其中j为u到v的一条最短路边。然后DP下就做完了。

#include<cstdio>
#include<cstring>
#define MN 1000
#define MM 4000
#define N 1024
#define lb long double
struct edge{int nx,t,w;lb c;}e[MM*2+5];
int n,h[MN+5],en,a[MN+5],d[MN+5],q[MN+5],qn,r[MN+5];
lb fk[MN+5],fj[MN+5],ans[MN+5];
inline void ins(int x,int y,int w,lb c)
{
    e[++en]=(edge){h[x],y,w,c};h[x]=en;
    e[++en]=(edge){h[y],x,w,c};h[y]=en;
}
struct data{int x,f;}t[N*2+5];
data min(data a,data b){return a.x<b.x?a:b;}
void change(int k,int x){for(t[k+=N].x=x;k>>=1;)t[k]=min(t[k<<1],t[k<<1|1]);}
void dj(int s)
{
    memset(d,127,sizeof(d));
    memset(t,127,sizeof(t));
    for(int i=1;i<=n;++i)t[i+N].f=i;
    for(change(s,d[s]=0);t[1].x<d[0];change(t[1].f,d[0]))
        for(int i=h[t[1].f];i;i=e[i].nx)if(d[t[1].f]+e[i].w<d[e[i].t])
            change(e[i].t,d[e[i].t]=d[t[1].f]+e[i].w);
}
void pre()
{
    int i,j;
    memset(r,0,sizeof(r));
    for(i=1;i<=n;++i)for(j=h[i];j;j=e[j].nx)
        if(d[i]+e[j].w==d[e[j].t])++r[e[j].t];
    for(i=1,qn=0;i<=n;++i)if(!r[i])q[++qn]=i;
    for(i=1;i<=qn;++i)
    {
        fk[q[i]]=i<2;
        for(j=h[q[i]];j;j=e[j].nx)
        {
            if(d[e[j].t]+e[j].w==d[q[i]])fk[q[i]]+=fk[e[j].t]*e[j].c;
            if(d[q[i]]+e[j].w==d[e[j].t]&&!--r[e[j].t])q[++qn]=e[j].t;
        }
    }
}
void solve(int s)
{
    int i,j;
    memset(r,0,sizeof(r));
    for(i=1;i<=n;++i)for(j=h[i];j;j=e[j].nx)
        if(d[i]+e[j].w==d[e[j].t])++r[i];
    for(i=1,qn=0;i<=n;++i)if(!r[i])q[++qn]=i;
    for(i=1;i<=qn;++i)
    {
        fj[q[i]]=0;
        for(j=h[q[i]];j;j=e[j].nx)
        {
            if(d[q[i]]+e[j].w==d[e[j].t])fj[q[i]]+=fj[e[j].t]*e[j].c;
            if(d[e[j].t]+e[j].w==d[q[i]]&&!--r[e[j].t])q[++qn]=e[j].t;
        }
        if(q[i]!=s)ans[q[i]]+=a[s]*fk[q[i]]*fj[q[i]];
        fj[q[i]]+=a[q[i]]/fk[q[i]];
    }
}
int main()
{
    int m,i,j,x,y,w;double c;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;++i)scanf("%d",&a[i]);
    while(m--)scanf("%d%d%d%lf",&x,&y,&w,&c),ins(x,y,w,c);
    for(i=1;i<=n;++i)dj(i),pre(),solve(i);
    for(i=1;i<=n;++i)printf("%.7lf\n",(double)ans[i]);
}

 

以上是关于2017-4-7校内训练的主要内容,如果未能解决你的问题,请参考以下文章

校内训练2019-11-15逮虾户

校内训练2019-11-15表演

20171129校内训练

「csp校内训练 2019-10-30」解题报告

三中校内训练净化

20171022校内训练