2017-10-12离线赛

来源:互联网 发布:stc单片机系统分析 编辑:程序博客网 时间:2024/06/02 06:26

氮氧碘磷初赛前的信心赛(AK场
16人AK= =

T1 prime

分析

线性筛模板(不

代码

#include<bits/stdc++.h>using namespace std;#define Komachi is retarded#define REP(i,a,b) for(int i=(a),i##_end_=(b);i<i##_end_;i++)#define DREP(i,a,b) for(int i=(a),i##_end_=(b);i>i##_end_;i--)#define chkmin(a,b) a=min(a,b)#define chkmax(a,b) a=max(a,b)#define LL long longvoid Rd(int &res){    char c;res=0;    while((c=getchar())<48);    do res=(res<<3)+(res<<1)+(c^48);    while((c=getchar())>47);}#define M 10000004int Pri[M>>1],pt,B[M];int Sum[M];void Init(){    B[1]=1;    REP(i,2,M){        if(!B[i])Pri[pt++]=B[i]=i;        REP(j,0,pt){            LL pos=1ll*Pri[j]*i;            if(pos>=M)break;            B[pos]=Pri[j];            if(!(i%Pri[j]))break;        }    }    REP(i,2,M){        int p=i/B[i];        Sum[i]=Sum[i-1]+(B[p]==p);    }}int Q;int main(){    Init();    Rd(Q);    while(Q--){        int L,R;        Rd(L),Rd(R);        printf("%d\n",Sum[R]-(L?Sum[L-1]:0));    }    return 0;}

T2 room

分析

显然钥匙数很少所以直接状态压缩
然后BFS

代码

#include<bits/stdc++.h>using namespace std;#define Komachi is retarded#define REP(i,a,b) for(int i=(a),i##_end_=(b);i<i##_end_;i++)#define DREP(i,a,b) for(int i=(a),i##_end_=(b);i>i##_end_;i--)#define chkmin(a,b) a=min(a,b)#define chkmax(a,b) a=max(a,b)#define LL long longvoid Rd(int &res){    char c;res=0;    while((c=getchar())<48);    do res=(res<<3)+(res<<1)+(c^48);    while((c=getchar())>47);}#define N 5004#define M 1044#define Mm 6444#define INF 0x3f3f3f3fint n,m,k;int Dis[N][M],S[N];int Next[Mm],V[Mm],W[Mm],Head[N],tot;void Add_Edge(int u,int v,int w){    Next[++tot]=Head[u],V[Head[u]=tot]=v,W[tot]=w;}#define LREP(i,A) for(int i=Head[A];i;i=Next[i])queue<int>Qx,Qy;void Solve(){    Dis[0][S[0]]=0;    while(!Qx.empty())Qx.pop();    while(!Qy.empty())Qy.pop();    Qx.push(0),Qy.push(S[0]);    while(!Qx.empty()){        int x=Qx.front();Qx.pop();        int y=Qy.front();Qy.pop();        if(x==n-1)return;        LREP(i,x){            if((y&W[i])!=W[i])continue;            int v=V[i],t=y|S[v];            if(Dis[v][t]==INF){                Dis[v][t]=Dis[x][y]+1;                Qx.push(v),Qy.push(t);            }        }    }}int main(){    memset(Dis,63,sizeof(Dis));    Rd(n),Rd(m),Rd(k);    REP(i,0,n){        int t;        REP(j,0,k){            Rd(t);            S[i]|=t<<j;        }    }    while(m--){        int u,v,w,t;        Rd(u),Rd(v);u--,v--;        w=0;        REP(j,0,k){            Rd(t);            w|=t<<j;        }        Add_Edge(u,v,w);    }    Solve();    int Ans=INF;    REP(i,0,1<<k) chkmin(Ans,Dis[n-1][i]);    if(Ans==INF)puts("No Solution");    else printf("%d\n",Ans);    return 0;}

T3 light

分析

求树上两条路径的交。
这个东西只要两两求LCA然后根据Dep排序即可。
然后感觉是非常水的。

代码

#include<bits/stdc++.h>using namespace std;#define Komachi is retarded#define REP(i,a,b) for(int i=(a),i##_end_=(b);i<i##_end_;i++)#define DREP(i,a,b) for(int i=(a),i##_end_=(b);i>i##_end_;i--)#define chkmin(a,b) a=min(a,b)#define chkmax(a,b) a=max(a,b)#define LL long longvoid Rd(int &res){    char c;res=0;    while((c=getchar())<48);    do res=(res<<3)+(res<<1)+(c^48);    while((c=getchar())>47);}#define M 200004int n,Q,Case,Next[M<<1],V[M<<1],Head[M],tot;void Add_Edge(int u,int v){    Next[++tot]=Head[u],V[Head[u]=tot]=v;}#define LREP(i,A) for(int i=Head[A];i;i=Next[i])int Dep[M],Top[M],Son[M],Sz[M],Fa[M];void DFS(int A,int f){    int B;    Sz[A]=1;    Dep[A]=Dep[f]+1;    Fa[A]=f;    LREP(i,A)if((B=V[i])!=f){        DFS(B,A);        Sz[A]+=Sz[B];        if(Sz[B]>Sz[Son[A]])Son[A]=B;    }}void FindTop(int A,int tp){    Top[A]=tp;    if(Son[A])FindTop(Son[A],tp);    int B;    LREP(i,A)if((B=V[i])!=Fa[A] && B!=Son[A])        FindTop(B,B);}int LCA(int A,int B){    while(Top[A]!=Top[B])        if(Dep[Top[A]]>Dep[Top[B]])A=Fa[Top[A]];        else B=Fa[Top[B]];    return Dep[A]<Dep[B]?A:B;}bool Cmp(int A,int B){return Dep[A]>Dep[B];}int Solve(int A,int B,int C){    int D=LCA(A,C),E=LCA(A,B),F=LCA(B,C);    int Tmp[]={B,D,E,F};    sort(Tmp,Tmp+4,Cmp);    return Dep[Tmp[0]]+Dep[Tmp[1]]-(Dep[LCA(Tmp[0],Tmp[1])]<<1)+1;}int main(){    Rd(n),Rd(Q),Rd(Case);    REP(i,1,n){        int u,v;        Rd(u),Rd(v);        Add_Edge(u,v);        Add_Edge(v,u);    }    DFS(1,0);    FindTop(1,1);    while(Q--){        int A,B,C;        Rd(A),Rd(B),Rd(C);        printf("%d\n",Solve(A,B,C));    }    return 0;}

总结

都说了是信心赛啊。
1 Hour 写完然后发呆一点都不好= =

原创粉丝点击