12
16
2015
0

Contest20151214滚粗记

又膜了场JSOI2015,壮烈垫底

条哥不知道去哪浪,先把题目放上了

为了比赛的公平性,我先陪神(S)犇(B)桢泼会儿隔膜

T1

看上去好像是DP,但不知道怎么转移。。

orz NiroBC AC

orz 神(S)犇(S)桢 40

正解是容斥,答案为:

三维枚举i,j,k套下公式就搞定辣。

 

#include<cstdio>
#include<algorithm>
using namespace std;
#define N 405
#define P 1000000007
int n,m,t,k,l;
long long ans;
long long c[N][N],d[N][N*N];
int main(){
    scanf("%d%d%d",&n,&m,&l);
    for (int i=0;i<=400;i++) c[i][0]=1;
    c[1][1]=1;
    for (int i=1;i<=max(n,max(m,l));i++)
        for (int j=1;j<=i;j++) c[i][j]=(c[i-1][j]+c[i-1][j-1])%P;
    for (int i=1;i<=401;i++) d[i][0]=1;
    for (int i=1;i<=l+1;i++) 
        for (int j=1;j<=n*m;j++) d[i][j]=(d[i][j-1]*i)%P;
    for (int i=0;i<=n;i++)
        for (int j=0;j<=m;j++)
            for (int k=0;k<=l;k++){
                long long s=c[n][i]*c[m][j]%P*c[l][k]%P*d[k+1][i*j]%P;
                if ((n+m+l-i-j-k)%2==0) ans=(ans+s)%P;else ans=(ans-s+P)%P;
            }
    printf("%lld\n",ans);
}

T2

这是一道水题(好吧其实是以前做过)

维护一个队列,里面存前面产生的gcd及产生该gcd的最左端。

易得队列有单调性,简单维护即可。

理论复杂度为n2,但实际复杂度较小(有很多gcd重复)。

然而。。有个变量没开long long然后滚粗了。。

 

#include<cstdio>
#include<algorithm>
using namespace std;
#define N 1001000
long long a[N],b[N],c[N];
int n,m,t;
long long k,l,s,ans;
long long gcd(long long a,long long b){
    if (a%b) return(gcd(b,a%b));
    else return(b);
}
int main(){
//  freopen("gcd.in","r",stdin);
//  freopen("gcd.out","w",stdout);
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
    for (int i=1;i<=n;i++){
        t=m;
        m=0;
        for (int j=1;j<=t;j++){
            k=gcd(b[j],a[i]);
            if (k!=b[m]){
                b[++m]=k;
                c[m]=c[j];
                ans=max(ans,b[m]*(i-c[m]+1));
            }
        }
        if (b[m]!=a[i]){
            b[++m]=a[i];
            c[m]=i;
            ans=max(ans,a[i]);
        }
    }
    printf("%lld\n",ans);
}

T3

一道十分复杂的题目(好吧其实是我懒。。)

首先对每条路径经过点新开一个点,上站的边权为1,下站和中途乘坐边权为0。

然后跑一遍最短路就求出第一问辣(SPFA会被卡飞,只能用堆优化dijkstra)。

然后处理出所有可能经过的点建新图(可以保证是有向无环图)。

按拓扑序求出最长距离就可以辣。

 

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
#define a first
#define b second
#define N 100100
using namespace std;
typedef unsigned long long ull;
typedef pair<int,int> PII;
const int M=5000010;
const int inf=2000000000;
 
pair<ull,int>a[M];
int n,m,y,t,st,ed,tmp,cnt,num,Num;
char s[50];
int head[M],vet[M],next[M],Head[M],Vet[M],Next[M],cost[M],init[M],dis[M],Dis[M],len[M][2],flag[M],x[M],q[M];
priority_queue<PII,vector<PII>,greater<PII> >Q;
int shit(){
    ull w=0;
    for (int i=0;i<strlen(s);i++) w=w*233+s[i];
    return(w);
}
int solve(){
    ull ss=shit();
    int ans=a[lower_bound(a+1,a+n+1,make_pair(ss,0))-a].b;
    return(ans);
}
void add(int a,int b,int c,int d){
    next[++num]=head[a];
    head[a]=num;
    vet[num]=b;
    len[num][0]=c;
    len[num][1]=d;
}
void Add(int a,int b,int c){
    Next[++Num]=Head[a];
    Head[a]=Num;
    Vet[Num]=b;
    cost[Num]=c;
    init[b]++;
}
int main(){
    scanf("%d%d",&m,&n);
    for (int i=1;i<=n;i++){
        scanf("%s",s);
        for (int j=0;j<strlen(s);j++)a[i].a=shit();
        a[i].b=i;
    }
    sort(a+1,a+n+1);
    cnt=n;
    for (int i=1;i<=m;i++){
        scanf("%d",&t);
        scanf("%s",s);
        x[1]=solve();
        add(x[1],++cnt,1,0);
        for (int j=2;j<=t;j++){
            scanf("%s",s);
            y=cnt,x[j]=solve();
            add(y,++cnt,0,1);
            add(x[j],cnt,1,0);
            add(cnt,x[j],0,0);
        }
        add(x[t],++cnt,1,0);
        for (int j=t-1;j>=1;j--){
            y=cnt;
            add(y,++cnt,0,1);
            add(x[j],cnt,1,0);
            add(cnt,x[j],0,0);
        }
    }
    scanf("%s",s);
    st=solve();
    scanf("%s",s);
    ed=solve();
    for (int i=1;i<=cnt;i++) dis[i]=inf;
    for (int i=1;i<=cnt;i++) flag[i]=0;
    Q.push(make_pair(0,st));dis[st]=0;
    while (!Q.empty()){
        int u=Q.top().b;Q.pop();
        if (flag[u])continue;
        flag[u]=1;
        for (int e=head[u];e;e=next[e]){
            int v=vet[e];
            if (dis[u]+len[e][0]<dis[v]){
                dis[v]=dis[u]+len[e][0];
                Q.push(make_pair(dis[v],v));
            }
        }
    }  
    for (int i=1;i<=cnt;i++)
        for (int e=head[i];e;e=next[e]){
            if (dis[i]+len[e][0]==dis[vet[e]]) Add(i,vet[e],len[e][1]);
        }
    int pre=1,tail=0;
    for (int i=1;i<=cnt;i++) if (init[i]==0) q[++tail]=i;
    while (pre<=tail){
        int u=q[pre++];
        for (int e=Head[u];e;e=Next[e]){
            int v=Vet[e];
            Dis[v]=max(Dis[v],Dis[u]+cost[e]);
            if ((--init[v])==0) q[++tail]=v;
        }
    }
    printf("%d\n",dis[ed]);
    printf("%d\n",Dis[ed]);
}
Category: 未分类 | Tags: | Read Count: 312

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com