氮氧碘磷初赛前的信心赛(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 long
void 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 10000004
int 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 long
void 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 0x3f3f3f3f
int 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 long
void 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 200004
int 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 写完然后发呆一点都不好= =