题解
终于最后一天了QAQ但还要赶作业来续命啊QAQ
今天的题比较水orz
第一题——小X的质数(prime)
【题目描述】
- 给出 Q   ( Q ≤ 1 0 7 ) Q\,(Q\leq 10^7) Q(Q≤107)组询问 [ l , r ] ( l , r ≤ 1 0 7 ) [l,r](l,r\leq10^7) [l,r](l,r≤107),求在区间内是质数或者是两个质数相乘的数的个数。
- 大水题
- 欧拉筛求出质数
- 暴力求出平方数
- 前缀和标记
- O ( 1 ) 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 − > B − d i s t L C A A B − > L C A B C dist_{LCA_{AC}->B}-dist_{LCA_{AB}->LCA_{BC}} distLCAAC−>B−distLCAAB−>LCABC
- 求一把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));
}
}