11月19日——NOIP2016 day1(考试期间没有推荐!!)(附code)

博主这几天在赶文化课进度,………………很忙…………所以就只发题和思路,代码以后补上(博主郑重承诺!!!)
PDF加密很严重……Nitor无法转成word,所以就委屈一下,我给你们我发的免费链接!!
http://download.csdn.net/detail/lemonoil/9687522
http://pan.baidu.com/s/1slSxJx7
第一道题是弱智模拟题(博主却错了……忘记判0……)
第二道题大神们用lca+差分或树链剖分解决了,博主zz,写了暴力;
第三题是dp+Floyd,但是我的记忆化搜索硬拼GG,还不如写dp。
综上所述,博主第一天完美GG并且第二天都救不回来了……
P.S.为什么NOIP难度上升这么快,等明年博主不还是GG?加油吧……!

toy

可惜了5分,没有判ans==0(mdzz);

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
#include<vector>
#include<string>
#define N 300005
#define NAME "toy"
using namespace std;
inline void readin(int &res){
    static char ch;
    while((ch=getchar())>'9'||ch<'0');
        res=ch-48;
    while((ch=getchar())<='9'&&ch>='0')
        res=res*10+ch-48;
}
int n,m,ans=1;
struct data{
    char njsz[100];
    int flag;
};
struct que{
    int flag,sum;
};
data a[N];
int main(){
    freopen(NAME".in","r",stdin);
    freopen(NAME".out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i].flag);
        scanf("%s",a[i].njsz);
    }
    for(int tot=1;tot<=m;tot++){
        que v;
        readin(v.flag);readin(v.sum);
        if(a[ans].flag==v.flag){
            ans-=(v.sum%n);
            if(ans<=0)ans+=n;
        }else{
            ans+=(v.sum%n);
            if(ans>n)ans-=n;
        }
    }
    printf("%s",a[ans].njsz);
    return 0;
}

running

这道题我交了个暴力(30分拿走不送)~~~
正解是lca+差分+树链剖分(听说启发式合并主席树可以险过……博主蒟蒻不懂……)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
#include<vector>
#include<string>
#define NAME "running"
#define N 400005
using namespace std;
int n,m,siz,cnt,tot,x,y;
int father[N],num[N],d[N],g[N][20],w[N],ans[N],root[N],size[N];
int first[N],next[N*3],to[N*3];
inline void readin(int &res){
    static char ch;
    while((ch=getchar())>'9'||ch<'0');
        res=ch-48;
    while((ch=getchar())<='9'&&ch>='0')
        res=res*10+ch-48;
}
struct node{
    int s,t,l;
}edge[N];
struct Tree{
    int lc,rc,s;
}T[N*30];
void inser(int x,int y){
    next[++siz]=first[x];
    first[x]=siz;
    to[siz]=y;
}
void dfs1(int x){
    size[x]=1,num[x]=++cnt;
    for (int k = 0;g[x][k];k++)g[x][k+1]=g[g[x][k]][k];
    for (int i = first[x];i;i=next[i])
        if (!father[to[i]]&&to[i]!=father[x]){
            father[to[i]]=g[to[i]][0] = x;
            d[to[i]]=d[x]+1;
            dfs1(to[i]);
            size[x] += size[to[i]];
        }
}
void add(int &v,int vv,int l,int r,int x){
    T[v = ++ tot]=T[vv];
    if(l==r){T[v].s++;return;}
    int mid=l+r>>1;
    if (x<=mid)add(T[v].lc,T[vv].lc,l,mid,x);
    else add(T[v].rc,T[vv].rc,mid+1,r,x);
    T[v].s++;
}
int query(int v,int vv,int l,int r,int x,int y){
    if(x<=l&&r<=y)return T[v].s-T[vv].s;
    int mid=l+r>>1,ret=0;
    if(x<=mid)ret+=query(T[v].lc,T[vv].lc,l,mid,x,y);
    if(mid<y)ret+=query(T[v].rc,T[vv].rc,mid+1,r,x,y);
    return ret;
}
int lca(int x,int y){
    if (d[x]<d[y])swap(x,y);
    for (int i=18;~i;i--)if(d[g[x][i]]>=d[y])x=g[x][i];
    if (x == y)return x;
    for (int i=18;~i;i--)if(g[x][i]^g[y][i])x=g[x][i],y=g[y][i];
    return g[x][0];
}
bool cmp_f(const node &a,const node &b){
    return d[a.s]<d[b.s]||d[a.s]==d[b.s]&&num[a.s]<num[b.s];
}

bool cmp_s(const node &a,const node &b){
    int d1=d[a.s]-a.l,d2 = d[b.s]-b.l;
    return d1<d2||d1==d2&&num[a.s]<num[b.s];
}

int seacher_f(int dep,int st){
    int l=0,r=m+1;
    while(l<r-1){
        int mid=l+r>>1;
        if(d[edge[mid].s]<dep||d[edge[mid].s]==dep&&num[edge[mid].s]<st)l=mid;
        else r=mid;
    }
    return l+1;
}

int seacher_s(int dep,int en){
    int l=0,r=m+1;
    while(l<r-1){
        int mid = l+r >> 1;
        if (d[edge[mid].s]>dep||d[edge[mid].s]==dep&&num[edge[mid].s]>en)r=mid;
        else l=mid;
    }
    return r-1;
}
int findl(int dep,int st){
    int l=0,r=m+1;
    while(l<r-1){
        int mid=l+r>>1;
        if(d[edge[mid].s]-edge[mid].l<dep||d[edge[mid].s]-edge[mid].l==dep&&num[edge[mid].s]<st)l=mid;
        else r=mid;
    }
    return l+1;
}

int findr(int dep,int en){
    int l=0,r=m+1;
    while (l<r-1){
        int mid=l+r>>1;
        if (d[edge[mid].s]-edge[mid].l>dep||d[edge[mid].s]-edge[mid].l==dep&&num[edge[mid].s]>en)r=mid;
        else l=mid;
    }
    return r-1;
}
int main(){
    freopen(NAME".in","r",stdin);
    freopen(NAME".out","w",stdout);
    readin(n);readin(m);
    for (int i=1;i<n;i++){
        readin(x);readin(y);
        inser(x,y),inser(y,x);
    }
    for (int i=1;i<=n;i++)readin(w[i]);
    dfs1(d[1]=1);
    for (int i=1;i<=m;i++){
        readin(edge[i].s);readin(edge[i].t);
        int z = lca(edge[i].s,edge[i].t);edge[i].l=d[edge[i].s]-d[z]+d[edge[i].t]-d[z];
        if (w[z]==d[edge[i].s]-d[z])ans[z]++;
    }
    sort(edge+1,edge+m+1,cmp_f);
    for(int i=1;i<=m;i++)
        add(root[i],root[i-1],1,n,num[edge[i].t]);
    for(int i=1;i<=n;i++){
        int l=seacher_f(d[i]+w[i],num[i]),r=seacher_s(d[i]+w[i],num[i]+size[i]-1);
        if (l<=r)ans[i]+=(num[i]>1?query(root[r],root[l-1],1,n,1,num[i]-1):0)+
                              (num[i]+size[i]<=n?query(root[r],root[l-1],1,n,num[i]+size[i],n):0);
    }

    for (int i=1;i<=n;i++)w[i]=n-w[i];
    for (int i=1;i<=m;i++)swap(edge[i].s,edge[i].t);
    sort(edge+1,edge+m+1,cmp_s);
    for (int i=1;i<=tot;i++)T[i].lc=T[i].rc=T[i].s=0;
    for (int i=1;i<=m;i++)
        add(root[i],root[i-1],1,n,num[edge[i].t]);
    for (int i = 1;i <= n;i ++){
        int l=findl(d[i]+w[i]-n,num[i]),r=findr(d[i]+w[i]-n,num[i]+size[i]-1);
        if(l<=r)ans[i]+=(num[i]>1?query(root[r],root[l-1],1,n,1,num[i]-1):0)+
                              (num[i]+size[i]<=n?query(root[r],root[l-1],1,n,num[i]+size[i],n):0);
    }
    for (int i=1;i<=n;i++)cout<<ans[i]<<' ';
    return 0;
}

classroom

说好的不考数学期望的呢?
(教练说dfs+floyd写得好的可以过……)
我写完floyd后硬是没有写出dfs……………………

#include<queue>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
using namespace std;
const int N = 2500;
const int Inf = 0x7fffffff;
queue < int > Q;
int n,m,C[N],D[N]; double P[N],F[N][N][2];
int v,E,f[N],p,dis[330][330];
bool use[N];
struct Edge{
    int to,from,w;
}e[200000];
inline int read(){
    int ret = 0,k = 1; char ch = getchar();
    while(ch < '0' || ch > '9'){if(ch == '-')k = -1; ch = getchar();}
    while(ch >= '0' && ch <= '9'){ret = ret*10 + ch-'0'; ch = getchar();}
    return ret * k;
}
inline void build(int x,int y,int w){
    e[++p].to = y; e[p].from = f[x]; e[p].w = w; f[x] = p;
    e[++p].to = x; e[p].from = f[y]; e[p].w = w; f[y] = p;
}
void Init(){
    n = read(); m = read(); v = read(); E = read();
    for(int i = 1; i <= n; ++i)C[i] = read();
    for(int i = 1; i <= n; ++i)D[i] = read();
    for(int i = 1; i <= n; ++i)scanf("%lf",&P[i]);
    for(int i = 1; i <= E; ++i){
        int x = read(),y = read(),w = read();
        if(x == y)continue;     build(x,y,w);
    }
}
void SPFA(int x){
    for(int i = 1; i <= v; ++i)dis[x][i] = Inf,use[i] = 0;
    Q.push(x); use[x] = 1; dis[x][x] = 0; 
    while(!Q.empty()){
        int u = Q.front(); Q.pop(); use[u] = 0;
        for(int i = f[u]; i ; i = e[i].from){
            int y = e[i].to;
            if(dis[x][y] > dis[x][u] + e[i].w){
                dis[x][y] = dis[x][u] + e[i].w;
                if(!use[y]){use[y] = 1; Q.push(y);}
            }
        }
    }
}
void Solve(){
    for(int i = 1; i <= v; ++i)SPFA(i);
    for(int i = 0; i <= n; ++i)
    for(int j = 0; j <= m; ++j)F[i][j][0] = F[i][j][1] = Inf;
    F[0][0][0] = 0;
    for(int i = 1; i <= n; ++i){
        F[i][0][0] = F[i-1][0][0] + dis[C[i-1]][C[i]];
    }
    C[0] = C[1]; D[0] = D[1]; F[1][1][1] = 0; F[1][1][0] = Inf;
    for(int i = 2; i <= n; ++i)
    for(int j = 1; j <= min(i,m); ++j){
        F[i][j][0] = min(F[i][j][0],F[i-1][j][0] + dis[C[i-1]][C[i]]);
        F[i][j][0] = min(F[i][j][0],F[i-1][j][1] + P[i-1]*dis[D[i-1]][C[i]] + (1-P[i-1])*dis[C[i-1]][C[i]]);
        F[i][j][1] = min(F[i][j][1],F[i-1][j-1][0] + P[i]*dis[C[i-1]][D[i]] + (1-P[i])*dis[C[i-1]][C[i]]);
        F[i][j][1] = min(F[i][j][1],F[i-1][j-1][1] + P[i]*P[i-1]*dis[D[i-1]][D[i]] + P[i]*(1-P[i-1])*dis[C[i-1]][D[i]]+ (1-P[i])*(P[i-1])*dis[D[i-1]][C[i]] + (1-P[i])*(1-P[i-1])*dis[C[i-1]][C[i]]);
    }
    double ans = Inf;
    for(int i = 0; i <= m; ++i){ans = min(ans,F[n][i][0]); ans = min(ans,F[n][i][1]);}
    printf("%.2f\n",ans);
}
int main(){
    freopen("classroom.in","r",stdin);
    freopen("classroom.out","w",stdout);
    Init();
    Solve();
    fclose(stdin);
    fclose(stdout);
    return 0;
}

这次考试就GG了………………
还是自己实力的问题…………

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值