noip2014解题报告

D2T3:

秦九韶算法

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=1e2+5;
const int maxm=1e7+5;
const ll P1=999653;
const ll P2=673313;
const ll P3=999983;
ll a[maxn][5],ans[maxm];
int n,m;
inline void read(int i){
    a[i][1]=a[i][2]=a[i][3]=0ll;
    ll b=1;
    char x=getchar();
    while(x<'0'||'9'<x){
        if(x=='-')b=-1;
        x=getchar();
    }
    while('0'<=x&&x<='9'){
    a[i][1]=( (a[i][1]<<1) + (a[i][1]<<3) + x-'0')%P1;    
    a[i][2]=( (a[i][2]<<1) + (a[i][2]<<3) + x-'0')%P2;    
    a[i][3]=( (a[i][3]<<1) + (a[i][3]<<3) + x-'0')%P3;    
    x=getchar();
    }
    a[i][1]*=b;
    a[i][2]*=b;
    a[i][3]*=b;
}
inline int read2(){
    int a=0;bool b=1;char x=getchar();
    while(x<'0'||'9'<x){
        if(x=='-')b=0;
        x=getchar();
    }
    while('0'<=x&&x<='9'){
        a=(a<<1)+(a<<3)+x-'0';
        x=getchar();
    }
    return b ? a : -a ;
}
int main()
{
    //freopen("equation.in","r",stdin);
    //freopen("equation.out","w",stdout);
    n=read2();m=read2();
    for(int i=0;i<=n;i++){
        read(i);
    } 
    for(int i=1;i<=m;i++){
        ll k1=0,k2=0,k3=0;
        for(int j=n;j>=0;j--){
            k1=(k1*i+a[j][1])%P1;
            k2=(k2*i+a[j][2])%P2;
            k3=(k3*i+a[j][3])%P3;
        }
        if( (!k1) && (!k2) && (!k3) )ans[ ++ans[0] ]=i;
    }
    for(int i=0;i<=ans[0];i++){
    printf("%lld\n",ans[i]);
    }
    return 0;
}
/*10457is prime
10459is prime
10463is prime*/

 D1T2:

树dp O(n):

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
const int P=10007;
const int maxn=2e5+5;
inline int read(){
    int a=0;bool b=1;char x=getchar();
    while(x<'0'||'9'<x){
        if(x=='-')b=0;
        x=getchar();
    }
    while('0'<=x&&x<='9'){
        a=(a<<1)+(a<<3)+x-'0';
        x=getchar();
    }
    return b ? a : -a ;
}
int first[maxn],next[maxn*2],to[maxn*2],edge_count;
inline void add(int x,int y){
    edge_count++;
    to[edge_count]=y;
    next[edge_count]=first[x];
    first[x]=edge_count;
}
int n,w[maxn],ans,sonmax[maxn],soncnt[maxn],f[maxn];
void search(int root ,int fa){
    sonmax[root]=f[root]=soncnt[root]=0;
    for(int i=first[root];i;i=next[i]){
        int v=to[i];
        if(v==fa)continue;
        
        search(v,root);
        f[root]=(f[root]+ w[root]*soncnt[v] + w[v]*soncnt[root]) % P;
        ans=max(ans,max ( w[root]*sonmax[v] ,  w[v]*sonmax[root] ) );
        soncnt[root]=(soncnt[root]+w[v])%P;
        sonmax[root]=max(sonmax[root],w[v]);
    }
}
int main()
{
    //freopen("link.in","r",stdin);
    //freopen("link.out","w",stdout);
    n=read();
    for(int i=1,u,v;i<n;i++){
        u=read();v=read();
        add(u,v);add(v,u);
    }
    for(int i=1;i<=n;i++){
        w[i]=read();
    }
    search(1,0);
    printf("%d ",ans);
    ans=0;
    for(int i=1;i<=n;i++){
        ans=(ans+f[i])%P;
    }
    printf("%d",(ans*2)%P);
    return 0;
}

或者

暴力 O(n):

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
const int P=10007;
const int maxn=2e5+5;
inline int read(){
    int a=0;bool b=1;char x=getchar();
    while(x<'0'||'9'<x){
        if(x=='-')b=0;
        x=getchar();
    }
    while('0'<=x&&x<='9'){
        a=(a<<1)+(a<<3)+x-'0';
        x=getchar();
    }
    return b ? a : -a ;
}
int n,w[maxn],ans[2];
int first[maxn],next[maxn*2],to[maxn*2],edge_count;
inline void add(int x,int y){
    edge_count++;
    to[edge_count]=y;
    next[edge_count]=first[x];
    first[x]=edge_count;
}
inline void solve(int u){
    int Max=0,sum=0;
    for(int i=first[u];i;i=next[i]){
        int v=to[i];
        
        ans[1]=(ans[1]+w[v]*sum)%P;
        ans[0]=max(ans[0],w[v]*Max);
        Max=max(Max,w[v]);
        sum=(sum+w[v])%P;
    }
}

int main()
{
    n=read();
    for(int i=1,u,v;i<n;i++){
        u=read();v=read();
        add(u,v);add(v,u);
    }
    for(int i=1;i<=n;i++){
        w[i]=read();
    }
    for(int i=1;i<=n;i++){
        solve(i);
    }
    printf("%d %d",ans[0],(ans[1]*2)%P);
    return 0;
}

D1T1:sb题

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=2e2+5;
inline int read(){
    int a=0;bool b=1;char x=getchar();
    while(x<'0'||'9'<x){
        if(x=='-')b=0;
        x=getchar();
    }
    while('0'<=x&&x<='9'){
        a=(a<<1)+(a<<3)+x-'0';
        x=getchar();
    }
    return b ? a : -a ;
}
int score[10][10]={
{0,0,1,1,0},
{1,0,0,1,0},
{0,1,0,0,1},
{0,0,1,0,1},
{1,1,0,0,0},
};
int n,na,nb,a[maxn],b[maxn],ansa,ansb;
int main()
{
    //freopen("rps.in","r",stdin);
    //freopen("rps.out","w",stdout);
    n=read();na=read();nb=read();
    for(int i=1;i<=na;i++)a[i]=read();
    for(int i=1;i<=nb;i++)b[i]=read();
    int pa=1,pb=1;    
    for(int i=1;i<=n;i++){
        ansa+=score[ a[pa] ][ b[pb] ];
        ansb+=score[ b[pb] ][ a[pa] ];
        pa++;pb++;
        if(pa==na+1)pa=1;
        if(pb==nb+1)pb=1;
    }
    printf("%d %d",ansa,ansb);
    return 0;
}

D1T3:

huge DP:

wa:

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=1e4+5;
const int maxm=1e3+5;
const int N=0x3f3f3f3f;
inline int read(){
    int a=0;bool b=1;char x=getchar();
    while(x<'0'||'9'<x){
        if(x=='-')b=0;
        x=getchar();
    }
    while('0'<=x&&x<='9'){
        a=(a<<1)+(a<<3)+x-'0';
        x=getchar();
    }
    return b ? a : -a ;
}
int n,m,k,up[maxn],down[maxn],f[maxn][maxm][2],p[maxn][2],ans1,ans2;
int now[maxm];
bool vis[maxn];
int main()
{
//    freopen("bird.in","r",stdin);
    //freopen("bird.out","w",stdout);
    
    memset(f,0x3f,sizeof(f));
    n=read();m=read();k=read();
    
    for(int i=1;i<=n;i++){
        up[i]=read();down[i]=read();
    }
    for(int i=0;i<=n;i++){
        p[i][0]=1;p[i][1]=m;
    }
    for(int i=1,P,L,H;i<=k;i++){
        P=read();L=read();H=read();
        p[P][0]=L+1;p[P][1]=H-1;
        vis[P]=1;
    }
    ans2=N;
    ans1=vis[0];
    
    for(int i=p[0][0];i<=p[0][1];i++){
        f[0][i][0]=f[0][i][1]=0;
    }
    for(int i=1;i<=n;i++){
        bool flag=0;
        for(int j=0;j<=m;j++){
            now[j]=N;
        }
        for(int j=1;j<=m;j++){
            
            if(p[i][0]<=j&&j<=p[i][1]){
                if(j+down[i]<=m)
                    f[i][j][0]=min(f[i-1][ j+down[i] ][0] , f[i-1][ j+down[i] ][1]);
                if(j>up[i])
                    f[i][j][1]=min( min( f[i-1][ j-up[i] ][0] , f[i-1][ j-up[i] ][1] ) , now[ j-up[i] ])+1;

                if(j==m){
                    for(int k=max(p[i-1][0],m-up[i]+1);k<=p[i-1][1];k++){
                        f[i][m][1]=min(f[i][m][1],min(  now[k]+1 , min(f[i-1][k][0]+1 , f[i-1][k][1]+1 ) ) );
                    }
                }
                
                int t=min(f[i][j][0],f[i][j][1]);
                if(t<N)flag=1;
                if(i==n)ans2=min(ans2,t);
            }
            if(j>up[i])now[j]=min( min( f[i-1][ j-up[i] ][0] , f[i-1][ j-up[i] ][1] ) , now[ j-up[i] ] )+1;
    }
    
    if(!flag){
        printf("0\n");
        printf("%d",ans1);
        return 0;
    }
    else ans1+=vis[i];  
}
    printf("1\n");
    printf("%d",ans2);
    return 0;
}

ac:

傻逼错因分析:

因为 本题的特殊要求,可以一直点击上升

所以每次的dp中 j==m时必须特判

但是有个问题,就是特判时状态从谁而来?

显然是 i-1 列的最大起始位置,也就是障碍物底端 和 m-up[i-1] 的 最大值

但是考虑到可以无限上升,所以此次转移的上届!!!必须到m!!!,否则就傻逼

 

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=1e4+5;
const int maxm=1e3+5;
const int N=0x3f3f3f3f;
inline int read(){
    int a=0;bool b=1;char x=getchar();
    while(x<'0'||'9'<x){
        if(x=='-')b=0;
        x=getchar();
    }
    while('0'<=x&&x<='9'){
        a=(a<<1)+(a<<3)+x-'0';
        x=getchar();
    }
    return b ? a : -a ;
}
int n,m,k,up[maxn],down[maxn],f[maxn][maxm][2],p[maxn][2],ans1,ans2;
int now[maxm];
bool vis[maxn];
int main()
{
    //freopen("bird.in","r",stdin);
    //freopen("bird.out","w",stdout);
    
    memset(f,0x3f,sizeof(f));
    n=read();m=read();k=read();
    
    for(int i=1;i<=n;i++){
        up[i]=read();down[i]=read();
    }
    for(int i=0;i<=n;i++){
        p[i][0]=1;p[i][1]=m;
    }
    for(int i=1,P,L,H;i<=k;i++){
        P=read();L=read();H=read();
        p[P][0]=L+1;p[P][1]=H-1;
        vis[P]=1;
    }
    /*for(int i=1;i<=50;i++){
        printf("%d ",up[i]);
    }
putchar('\n');
    for(int i=1;i<=50;i++){
        printf("%d ",down[i]);
    }
    putchar('\n');*/调试过程忽略
    ans2=N;
    ans1=vis[0];
    for(int i=p[0][0];i<=p[0][1];i++){
        f[0][i][0]=f[0][i][1]=0;
    }
    for(int i=1;i<=n;i++){
        bool flag=0;
        for(int j=0;j<=m;j++){
            now[j]=N;
        }
        for(int j=1;j<=m;j++){
            if(p[i][0]<=j&&j<=p[i][1]){
                if(j+down[i]<=m)
                    f[i][j][0]=min(f[i-1][ j+down[i] ][0] , f[i-1][ j+down[i] ][1]);
                if(j>up[i])
                    f[i][j][1]=min( min( f[i-1][ j-up[i] ][0] , f[i-1][ j-up[i] ][1] ) , now[ j-up[i] ])+1;

                if(j==m){//特判:注意k的终止边界  从k<=p[i-1][1] 变成 k<=m
                    for(int k=max(p[i-1][0],m-up[i]+1);k<=m;k++){
                        f[i][m][1]=min(f[i][m][1],min(  now[k]+1 , min(f[i-1][k][0]+1 , f[i-1][k][1]+1 ) ) );
                    }
                }
                
                int t=min(f[i][j][0],f[i][j][1]);
                if(t<N)flag=1;//printf("%d %d\n",i,j);                
                if(i==n)ans2=min(ans2,t);
            }
            if(j>up[i])now[j]=min( min( f[i-1][ j-up[i] ][0] , f[i-1][ j-up[i] ][1] ) , now[ j-up[i] ] )+1;
    }
    
    if(!flag){
        printf("0\n");
        printf("%d",ans1);
        return 0;
    }
    else ans1+=vis[i];  
}
    printf("1\n");
    printf("%d",ans2);
    return 0;
}

 D2T2:

wa:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<functional>
using namespace std;
const int maxn=1e4+5;
const int maxm=2e5+5;
const int N=0x3f3f3f3f;
inline int read(){
    int a=0;bool b=1;char x=getchar();
    while(x<'0'||'9'<x){
        if(x=='-')b=0;
        x=getchar();
    }
    while('0'<=x&&x<='9'){
        a=(a<<1)+(a<<3)+x-'0';
        x=getchar();
    }
    return b ? a : -a ;
}
int first[maxn][2],next[maxm][2],to[maxm][2],edge_count[2];
inline void add(int x,int y,int b){
    edge_count[b]++;
    to[edge_count[b]][b]=y;
    next[edge_count[b]][b]=first[x][b];
    first[x][b]=edge_count[b];
}
int dfn[maxn],S[maxn],low[maxn],Time,p,scc[maxn],temp;
void tarjan(int u){
    dfn[u]=low[u]=++Time;
    S[++p]=u;
    for(int i=first[u][0];i;i=next[i][0]){
        int v=to[i][0];
        if(!dfn[v]){
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(!scc[v])low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        temp++;
        while(S[p+1]!=u){
            scc[ S[p] ]=temp;
            p--;
        }
    }
}
int n,m,s,t;
bool acp[maxn],vis[maxn];//acp[i]璇ョ偣鏄惁鑳藉埌杈剧粓鐐?vis[i]!!!璇ュ己鑱旈€氬垎閲?!!鏄惁琚玝fs鍒?
inline void bfs(int x){
    int front=0,rear=0;
    S[rear++]=x;
    vis[x]=1;
    while(front<rear){
        int u=S[front];
        for(int i=first[u][1];i;i=next[i][1]){
            int v=to[i][1];
            if(!vis[v]){
                vis[v]=1;
                S[rear++]=v;
            }
        }
        front++;
    }
    
}
inline void solve(int u){
    acp[u]=1;
    for(int i=first[u][0];i;i=next[i][0]){
        int v=to[i][0];
        if(!vis[ scc[v] ]){acp[u]=0;break;}
    }
}
int dis[maxn];
priority_queue<pair<int,int> ,vector<pair<int,int> > ,less<pair<int,int> > >q;
//acp[i]璇ョ偣鏄惁鑳藉埌杈剧粓鐐?vis[i]璇ョ偣鏄惁姹傚嚭鏈€鐭矾
inline void dijkstra(int s,int t){
    memset(dis,0x3f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dis[s]=0;
    
    q.push(make_pair(0,s));
    while(q.size()){
        int pos=q.top().second;
        q.pop();
        if(vis[pos])continue;
        
        vis[pos]=1;
        for(int i=first[pos][0];i;i=next[i][0]){
            int v=to[i][0];
            if(vis[v] || !acp[v])continue;
            
            int k=dis[pos]+1;
            if(k<dis[v]){dis[v]=k;q.push(make_pair(dis[v],v));}
        }
    }
}
bool link[maxn][maxn];
int main()
{
    //freopen("road.in","r",stdin);
    //freopen("road.out","w",stdout);
    n=read();m=read();
    for(int i=1,u,v;i<=m;i++){
        u=read();v=read();
        if(!link[u][v] && u!=v)add(u,v,0);//鍒ら噸杈癸紵锛熸湁鐢紵
        link[u][v]=1;
    }
    s=read();t=read();
    for(int i=1;i<=n;i++){
        if(!dfn[i])tarjan(i);
    }
    for(int i=1;i<=n;i++){
        for(int j=first[i][0];j;j=next[j][0]){
            if(scc[i]==scc[ to[j][0] ])continue;
            add(scc[ to[j][0] ],scc[i],1);//鍙嶅悜寤鸿竟bfs锛堬級
        }
    }
    bfs(scc[ t ]);
    for(int i=1;i<=n;i++){
        if(vis[ scc[i] ])solve(i);
    }
    dijkstra(s,t);
    printf("%d ",dis[t]==N?-1:dis[t]);
    //for(int i=1;i<=n;i++){printf("%d ",dis[i]);}
    return 0;
}

ac?:

D2T2:

wa:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<functional>
using namespace std;
const int maxn=1e4+5;
const int maxm=2e5+5;
const int N=0x3f3f3f3f;
inline int read(){
    int a=0;bool b=1;char x=getchar();
    while(x<'0'||'9'<x){
        if(x=='-')b=0;
        x=getchar();
    }
    while('0'<=x&&x<='9'){
        a=(a<<1)+(a<<3)+x-'0';
        x=getchar();
    }
    return b ? a : -a ;
}
int first[maxn][2],next[maxm][2],to[maxm][2],edge_count[2];
inline void add(int x,int y,int b){
    edge_count[b]++;
    to[edge_count[b]][b]=y;
    next[edge_count[b]][b]=first[x][b];
    first[x][b]=edge_count[b];
}
int dfn[maxn],S[maxn],low[maxn],Time,p,scc[maxn],temp;
void tarjan(int u){
    dfn[u]=low[u]=++Time;
    S[++p]=u;
    for(int i=first[u][0];i;i=next[i][0]){
        int v=to[i][0];
        if(!dfn[v]){
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(!scc[v])low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        temp++;
        while(S[p+1]!=u){
            scc[ S[p] ]=temp;
            p--;
        }
    }
}
int n,m,s,t;
bool acp[maxn],vis[maxn];//acp[i]璇ョ偣鏄惁鑳藉埌杈剧粓鐐?vis[i]!!!璇ュ己鑱旈€氬垎閲?!!鏄惁琚玝fs鍒?
inline void bfs(int x){
    int front=0,rear=0;
    S[rear++]=x;
    vis[x]=1;
    while(front<rear){
        int u=S[front];
        for(int i=first[u][1];i;i=next[i][1]){
            int v=to[i][1];
            if(!vis[v]){
                vis[v]=1;
                S[rear++]=v;
            }
        }
        front++;
    }
    
}
inline void solve(int u){
    acp[u]=1;
    for(int i=first[u][0];i;i=next[i][0]){
        int v=to[i][0];
        if(!vis[ scc[v] ]){acp[u]=0;break;}
    }
}
int dis[maxn];
priority_queue<pair<int,int> ,vector<pair<int,int> > ,less<pair<int,int> > >q;
//acp[i]璇ョ偣鏄惁鑳藉埌杈剧粓鐐?vis[i]璇ョ偣鏄惁姹傚嚭鏈€鐭矾
inline void dijkstra(int s,int t){
    memset(dis,0x3f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dis[s]=0;
    
    q.push(make_pair(0,s));
    while(q.size()){
        int pos=q.top().second;
        q.pop();
        if(vis[pos])continue;
        
        vis[pos]=1;
        for(int i=first[pos][0];i;i=next[i][0]){
            int v=to[i][0];
            if(vis[v] || !acp[v])continue;
            
            int k=dis[pos]+1;
            if(k<dis[v]){dis[v]=k;q.push(make_pair(dis[v],v));}
        }
    }
}
bool link[maxn][maxn];
int main()
{
    //freopen("road.in","r",stdin);
    //freopen("road.out","w",stdout);
    n=read();m=read();
    for(int i=1,u,v;i<=m;i++){
        u=read();v=read();
        if(!link[u][v] && u!=v)add(u,v,0);//鍒ら噸杈癸紵锛熸湁鐢紵
        link[u][v]=1;
    }
    s=read();t=read();
    for(int i=1;i<=n;i++){
        if(!dfn[i])tarjan(i);
    }
    for(int i=1;i<=n;i++){
        for(int j=first[i][0];j;j=next[j][0]){
            if(scc[i]==scc[ to[j][0] ])continue;
            add(scc[ to[j][0] ],scc[i],1);//鍙嶅悜寤鸿竟bfs锛堬級
        }
    }
    bfs(scc[ t ]);
    for(int i=1;i<=n;i++){
        if(vis[ scc[i] ])solve(i);
    }
    dijkstra(s,t);
    printf("%d ",dis[t]==N?-1:dis[t]);
    //for(int i=1;i<=n;i++){printf("%d ",dis[i]);}
    return 0;
}

 

posted @ 2019-05-03 15:47  Tj1  阅读(114)  评论(0编辑  收藏  举报