HGOI-国庆七连测-day7-

题解

终于最后一天了QAQ但还要赶作业来续命啊QAQ
今天的题比较水orz


第一题——小X的质数(prime)

【题目描述】

  • 给出 Q   ( Q 1 0 7 ) Q\,(Q\leq 10^7) 组询问 [ l , r ] ( l , r 1 0 7 ) [l,r](l,r\leq10^7) ,求在区间内是质数或者是两个质数相乘的数的个数。

  • 大水题
  • 欧拉筛求出质数
  • 暴力求出平方数
  • 前缀和标记
  • O ( 1 ) O(1) 出解

#include <bits/stdc++.h>
#define LL long long
using namespace std;

void fff(){
	freopen("prime.in","r",stdin);
	freopen("prime.out","w",stdout);
}
const int N=1e7+10;
inline int read(){
	int x=0;char ch=getchar();
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	return x;
}
int prime[N],prime_num;
bool visited[N];
int sum[N];
void oula(){
	prime_num=0;
	for(int i=2;i<N;i++){
		if(!visited[i])
			prime[++prime_num]=i;
		for(int j=1;j<=prime_num&&prime[j]*i<N;j++){
			visited[i*prime[j]]=true;
			if(i%prime[j]==0) break;
		}
	}
	visited[1]=true;
	for(int i=1;i<prime_num;i++){
		for(int j=i;j<prime_num;j++){
			if((LL)prime[i]*prime[j]>=N) break;
			visited[prime[i]*prime[j]]=false;
		}
	}
	for(int i=1;i<N;i++){
		sum[i]=sum[i-1]+(!visited[i]);
	}
}
int Q;
int main(){
//	fff();
	oula();
	Q=read();
	while(Q--){
		int l,r;
		l=read(),r=read();
		printf("%d\n",sum[r]-sum[l-1]);
	}
	return 0;
}

第二题——小X的密室(room)

  • 这道题之前我做过orz,直接贴密室

第三题——小X的佛光(light)

【题目描述】

  • 给出一颗无向树,给出Q次查询,每次询问ABC,求A-B,A-C的公共路径的长度。

  • 这个裸的LCA,两个的公共路径长度就是 d i s t L C A A C &gt; B d i s t L C A A B &gt; L C A B C dist_{LCA_{AC}-&gt;B}-dist_{LCA_{AB}-&gt;LCA_{BC}}
  • 求一把LCA解决一切问题。

#include <bits/stdc++.h>
using namespace std;
void fff(){
	freopen("light.in","r",stdin);
	freopen("light.out","w",stdout);
}
inline int read(){
	int x=0;char ch=getchar();
	while(ch<'0'||ch>'9') ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	return x;
}
const int N=2e5+10;
struct Edge{
	int u,v;
};
vector<Edge> edge;
vector<int> G[N];
int n,q,NUM;
int dep[N],visited[N];
int fa[N][21];
void dfs(int u,int depth){
	visited[u]=true;
	dep[u]=depth;
	int siz=G[u].size();
	for(int i=0;i<siz;i++){
		Edge &e=edge[G[u][i]];
		if(visited[e.v]) continue;
		fa[e.v][0]=u;
		dfs(e.v,depth+1);
	}
}
void st(){
	for(int j=1;j<=20;j++)
		for(int i=1;i<=n;i++)
			fa[i][j]=fa[fa[i][j-1]][j-1];
}
inline int LCA(int x,int y){
	if(dep[x]<dep[y]) swap(x,y);
	for(int i=20;i>=0;i--){
		if(dep[fa[x][i]]>=dep[y])
			x=fa[x][i];
	}
	if(x==y) return x;
	for(int i=20;i>=0;i--){
		if(fa[x][i]!=fa[y][i]){
			x=fa[x][i];
			y=fa[y][i];
		}
	}
	if(fa[x][0]!=fa[y][0]){
			x=fa[x][0];
			y=fa[y][0];
	}
	return fa[x][0];
}
inline int get_ans(int A,int B,int C){
	if(A>C) swap(A,C);
	int LCA_AC=LCA(A,C),LCA_AB=LCA(A,B),LCA_BC=LCA(B,C),LCA_ABC=LCA(LCA_AC,B);
	return (dep[LCA_AC]+dep[B]-2*dep[LCA_ABC]+1)-(dep[LCA_AB]+dep[LCA_BC]-2*dep[LCA_ABC]+1)+1;
}
int main(){
//	fff();
	n=read(),q=read(),NUM=read();
	for(int i=1;i<n;i++){
		int u,v;
		u=read(),v=read();
		edge.push_back((Edge){u,v});
		G[u].push_back(edge.size()-1);
		edge.push_back((Edge){v,u});
		G[v].push_back(edge.size()-1);
	}
	dfs(1,1);
	st();
	while(q--){
		int A,B,C;
		A=read(),B=read(),C=read();
		printf("%d\n",get_ans(A,B,C));
	}
}

猜你喜欢

转载自blog.csdn.net/qq_42037034/article/details/82957563