[CF474F]
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF474F]相关的知识,希望对你有一定的参考价值。
题意:多次询问区间[l,r]中不是lca(xl...xr)的数的个数
先用线段树找出区间lca,然后用可持久化trie统计区间中是lca的数有多少个
1 #include<stdio.h>
2 #define loga 29
3 int tot,M,Tgcd[300000],root[100010],ch[4000000][2],size[4000000];
4 int gcd(int a,int b){
5 if(a==0){
6 if(b==0)return 0;
7 return b;
8 }
9 if(b==0)return a;
10 if(a%b==0)return b;
11 return gcd(b,a%b);
12 }
13 int querygcd(int s,int t){
14 int ans=Tgcd[s+M];
15 for(s+=M-1,t+=M+1;s^t^1;s>>=1,t>>=1){
16 if(~s&1)ans=gcd(ans,Tgcd[s^1]);
17 if(t&1)ans=gcd(ans,Tgcd[t^1]);
18 }
19 return ans;
20 }
21 void insert(int lroot,int rroot,int v,int p){
22 size[rroot]=size[lroot]+1;
23 if(p<0)return;
24 ch[rroot][((v>>p)&1)^1]=ch[lroot][((v>>p)&1)^1];
25 tot++;
26 ch[rroot][(v>>p)&1]=tot;
27 insert(ch[lroot][(v>>p)&1],ch[rroot][(v>>p)&1],v,p-1);
28 }
29 int querynum(int lroot,int rroot,int v,int p){
30 if(p<0)return size[rroot]-size[lroot];
31 if(ch[rroot][(v>>p)&1]==0)return 0;
32 return querynum(ch[lroot][(v>>p)&1],ch[rroot][(v>>p)&1],v,p-1);
33 }
34 int main(){
35 int n,m,i,j;
36 scanf("%d",&n);
37 for(M=1;M<n+2;M<<=1);
38 for(i=1;i<=n;i++){
39 scanf("%d",Tgcd+M+i);
40 tot++;
41 root[i]=tot;
42 insert(root[i-1],root[i],Tgcd[M+i],loga);
43 }
44 for(i=M-1;i>0;i--)Tgcd[i]=gcd(Tgcd[i<<1],Tgcd[i<<1|1]);
45 scanf("%d",&m);
46 while(m--){
47 scanf("%d%d",&i,&j);
48 printf("%d\n",j-i+1-querynum(root[i-1],root[j],querygcd(i,j),loga));
49 }
50 }
以上是关于[CF474F]的主要内容,如果未能解决你的问题,请参考以下文章