zoukankan      html  css  js  c++  java
  • [Lydsy1805月赛]口算训练 BZOJ5358

    分析:

    没想到这道题还能二分查找...

    这题主席树的话,裸的很显然...我们将每一个数分解质因数,之后建一个可持久化权值线段树维护[L,R]区间内的每一种质因子的个数,分解质因数的话,可以选择用线筛,总体时间复杂度为O(qlognlogn+nlogn+n);之后的常数巨大,比根号跑的还慢...当然,主席树可以只维护质数,这样能减少一个log,快上不少。

    附上代码:

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <queue>
    #include <iostream>
    using namespace std;
    #define N 100005
    #define maxn 100000
    #define lson l,m,tr[rt].ls
    #define rson m+1,r,tr[rt].rs
    #define clear(rt) tr[rt].ls=tr[rt].rs=tr[rt].siz=0
    struct node
    {
    	int ls,rs,siz;
    }tr[N*200];
    inline char nc() {
        static char buf[100000],*p1,*p2;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int rd() {
        int x=0;char s=nc();
        while(s<'0'||s>'9') s=nc();
        while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+s-'0',s=nc();
        return x;
    }
    int rot[N],pri[N],vis[N],p[N],n,Q,a[N],cnt;
    void init()
    {
    	int num=0;
    	for(int i=2;i<N;i++)
    	{
    		if(!vis[i])
    		{
    			pri[++num]=i;
    			p[i]=i;
    		}
    		for(int j=1;j<=num&&i*pri[j]<N;j++)
    		{
    			vis[i*pri[j]]=1;p[i*pri[j]]=pri[j];
    			if(i%pri[j]==0)break;
    		}
    	}
    }
    void insert(int x,int v,int c,int l,int r,int &rt)
    {
    	rt=++cnt,clear(cnt);
    	if(l==r){tr[rt].siz=tr[x].siz+c;return ;}
    	int m=(l+r)>>1;
    	if(m>=v)tr[rt].rs=tr[x].rs,insert(tr[x].ls,v,c,lson);
    	else tr[rt].ls=tr[x].ls,insert(tr[x].rs,v,c,rson);
    	tr[rt].siz=tr[tr[rt].ls].siz+tr[tr[rt].rs].siz;
    }
    int query(int x,int v,int l,int r,int rt)
    {
    	//if(l==r)printf("%d %d %d
    ",l,r,tr[rt].siz-tr[x].siz);
    	if(l==r)return tr[rt].siz-tr[x].siz;
    	int m=(l+r)>>1;
    	if(m>=v)return query(tr[x].ls,v,lson);
    	return query(tr[x].rs,v,rson);
    }
    int main()
    {
    	int T;T=rd();
    	init();
    	while(T--)
    	{
    		rot[0]=cnt=0;
    		n=rd();Q=rd();
    		for(int i=1;i<=n;i++)
    		{
    			a[i]=rd();rot[i]=rot[i-1];
    			int t=a[i];
    			while(t!=1)insert(rot[i],p[t],1,1,maxn,rot[i]),t=t/p[t];
    		}
    		while(Q--)
    		{
    			int x,y,z;
    			x=rd();y=rd();z=rd();
    			int t=z,u=0;
    			while(t!=1)
    			{
    				//printf("%d
    ",p[t]);
    				if(query(rot[x-1],p[t],1,maxn,rot[y]))
    				{
    					insert(rot[y],p[t],-1,1,maxn,rot[y]);
    				}else
    				{
    					u=1;
    					puts("No");
    					break;
    				}
    				t=t/p[t];
    			}
    			while(z!=t)
    			{
    				insert(rot[y],p[z],1,1,maxn,rot[y]);
    				z=z/p[z];
    			}
    			if(!u)puts("Yes");
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    [Scala] akka actor编程(一)
    随便说说
    [Java] Java执行Shell命令
    [Scala] Scala基础知识
    [Linux] 账户管理命令(二)
    [Linux] 账户管理命令(一)
    [Kerberos] Java client访问kerberos-secured cluster
    沟通与影响技术培训
    Python
    ML 基础知识
  • 原文地址:https://www.cnblogs.com/Winniechen/p/9107822.html
Copyright © 2011-2022 走看看