zoukankan      html  css  js  c++  java
  • BZOJ4026 dC loves Number Throry

    BZOJ4026 dC Loves Number Theory

    题目传送门

    题解

    什么鬼畜题目看了标题之后感觉很慌,以为是数论题,看了题目之后也没有思路,只能去求助由乃大神了。解答了一番之后感觉挺可做的。由于欧拉函数的计算公式是这样的(phi(n)=n*prod frac{pi-1}{pi}),所以我们会发现一段区间内的数乘积的欧拉函数的值只和这几个元素的质因数有关,这些区间内所有元素的质因数都会且仅会被记一次贡献(即如果有两个元素有相同的质因数,那么这个质因数做出的贡献仍然是一次)。所以我们可以先预处理出在1到(Mx)内的质数,然后剩下要做的就是统计([l,r])区间出现了那些质因数。如果没有强制在线的话倒是可以用莫队强上,但是由于题目强制在线了,我们就只能套上主席树了。主席树上每个点记录第(i)个元素每个质因数做出的贡献,但由于这样子一个区间内同一个质因数的贡献可能会被算多次,所以我们规定只把每个质因数的贡献算在最右边的一个元素上,这样就可以实现不重复贡献计算了。最后实际上就是在以(rt[r])这个线段树上查询([l,r])区间的乘积就行了。这样子预处理质数和建主席树的复杂度为(O(nsqrt{n}+nlog^2(n)))的,然后每次询问的复杂度就是(O(nlog(n)))的。不过还要注意的是,这里的主席书的空间要开(nlog^2(n))的,因为每一个点的质因数最多有(log)个,对于每个质因数修改会多出(log)个节点,所以要开(nlog^2(n))的空间。。(因为这个RE了无数遍
    话说似乎还有十字链表的做法,不明觉厉。。。

    Code

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    bool Finish_read;
    template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
    template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}
    template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('
    ');}
    template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
    /*================Header Template==============*/
    #define PAUSE printf("Press Enter key to continue..."); fgetc(stdin);
    const int N=1e5+500;
    const ll Md=1e6+777;
    int n,q,cnt,ans;
    int a[N],Mx;
    int last[N],pri[Md],vis[Md],rt[N];
    /*==================Define Area================*/
    namespace PersistentSegmentTree {
    	struct node {
    		int ls,rs;
    		ll val;
    	}t[N*160];
    	int tot;
    	void Modify(int& newrt,int rt,int l,int r,int pos,int v) {
    		if(l>r) return ;
    		if(!newrt||newrt==rt) newrt=++tot,t[newrt].val=t[rt].val*v%Md;
    		else t[newrt].val=t[newrt].val*v%Md;
    		if(l==r) return ;
    		int mid=(l+r)>>1;
    		if(pos<=mid) {
    			if(!t[newrt].rs) t[newrt].rs=t[rt].rs;
    			Modify(t[newrt].ls,t[rt].ls,l,mid,pos,v);
    		}	
    		else {
    			if(!t[newrt].ls) t[newrt].ls=t[rt].ls;
    			Modify(t[newrt].rs,t[rt].rs,mid+1,r,pos,v);
    		}
    	}
    	ll Query(int o,int l,int r,int L,int R) {
    		if(L<=l&&r<=R) return t[o].val;
    		int mid=(l+r)>>1;
    		if(R<=mid) return Query(t[o].ls,l,mid,L,R);
    		if(L>mid) return Query(t[o].rs,mid+1,r,L,R);
    		return Query(t[o].ls,l,mid,L,R)*Query(t[o].rs,mid+1,r,L,R)%Md;
    	}
    }
    using namespace PersistentSegmentTree;
    
    ll Powe(ll x,ll y) {
    	ll res=1;
    	while(y) {
    		if(y&1) res*=x,res%=Md;
    		x*=x;x%=Md;
    		y>>=1;
    	}
    	return res;
    }
    
    int main() {
    	read(n);read(q);
    	for(int i=1;i<=n;i++) {
    		read(a[i]);
    		Mx=max(Mx,a[i]);
    	}
    	for(int i=2;i<=Mx;i++) {
    		if(!vis[i]) vis[i]=++cnt,pri[cnt]=i;
    		for(int j=i*2;j<=Mx;j+=i) vis[j]=-1;
    	}
    	t[0].val=1;
    	for(int i=1;i<=n;i++) {
    		if(a[i]==1) {
    			Modify(rt[i],rt[i-1],1,n,i,1);
    			continue ;
    		}
    		for(int j=1;j<=cnt&&pri[j]*pri[j]<=a[i];j++) {
    			if(a[i]%pri[j]==0) {
    				a[i]/=pri[j];Modify(rt[i],rt[i-1],1,n,i,pri[j]-1);
    				while(a[i]%pri[j]==0) a[i]/=pri[j],Modify(rt[i],rt[i-1],1,n,i,pri[j]);
    				if(last[j]) Modify(rt[i],rt[i-1],1,n,last[j],Powe(pri[j]-1,Md-2)*pri[j]%Md);
    				last[j]=i;
    			}
    		}
    		if(a[i]>1) {
    			int j=vis[a[i]];
    			if(last[j]) Modify(rt[i],rt[i-1],1,n,last[j],Powe(pri[j]-1,Md-2)*pri[j]%Md);
    			last[j]=i;Modify(rt[i],rt[i-1],1,n,i,pri[j]-1);
    		}
    	}
    	for(int i=1,l,r;i<=q;i++) {
    		read(l);read(r);
    		l^=ans,r^=ans;
    		ans=Query(rt[r],1,n,l,r);
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
    「我不敢下苦功琢磨自己,怕终于知道自己并非珠玉;然而心中既存着一丝希冀,便又不肯甘心与瓦砾为伍。」
  • 相关阅读:
    原生Python机器学习分类之一Knn算法
    Java可视化文件(夹)加密解密压缩解压
    基于图搜索技术的八数码问题求解C++
    遗传算法解决TSP问题
    简单dp
    并查集
    KMP算法
    快速迭代
    为什么vs2017在代码右键上没有vs2013(第一个图)上实现抽象类这个选项?
    关于C#面向对象中的查看类图(没有此按键的问题)的解决方法 The solution to view class diagrams in C # object-oriented (without this key)
  • 原文地址:https://www.cnblogs.com/Apocrypha/p/9544396.html
Copyright © 2011-2022 走看看