zoukankan      html  css  js  c++  java
  • [BZOJ4026]dC Loves Number Theory 欧拉函数+线段树

    链接

    题意:给定长度为 (n) 的序列 A,每次求区间 ([l,r]) 的乘积的欧拉函数

    题解

    考虑离线怎么搞,将询问按右端点排序,然后按顺序扫这个序列

    对于每个 (A_i) ,枚举它的质因数,由于不同的质因数只算一次,所以我们只关心每个质数它最后一次出现的位置,开一棵线段树维护一下每个位置的质数,加入新的质数时,先把之前的删掉,再加新的

    现在强制在线,可以开可持久化线段树维护一下

    #include<bits/stdc++.h>
    #define REP(i,a,b) for(int i(a);i<=(b);++i)
    #define dbg(...) fprintf(stderr,__VA_ARGS__)
    const int S=1<<18;
    char ibuf[S],*iS,*iT;
    #define gc (iS==iT?iT=ibuf+fread(iS=ibuf,1,S,stdin),iS==iT?EOF:*iS++:*iS++)
    inline int read(){char c,p=0;int w;
    	while(isspace(c=gc));if(c=='-')p=1,c=gc;w=c&15;
    	while(isdigit(c=gc))w=w*10+(c&15);return p?-w:w;
    }
    
    template<typename T,typename U>inline bool smin(T&x,const U&y){return x>y?x=y,1:0;}
    template<typename T,typename U>inline bool smax(T&x,const U&y){return x<y?x=y,1:0;}
    const int N=50005,M=1e6+999,p=1e6+777;
    int n,pr[1105],pre[M],inv[M],mul[N];
    bool np[1105];
    struct node{int ls,rs,w;}t[N*100];
    int rt[N],cnt;
    inline void ins(int&o,int l,int r,int x,int v){
    	t[++cnt]=t[o];o=cnt;t[o].w=1ll*t[o].w*v%p;
    	if(l==r)return;int mid=l+r>>1;
    	x<=mid?ins(t[o].ls,l,mid,x,v):ins(t[o].rs,mid+1,r,x,v);
    }
    inline int ask(int o,int l,int r,int x){
    	if(x<=l)return t[o].w;
    	if(x>r)return 1;int mid=l+r>>1;
    	return 1ll*ask(t[o].ls,l,mid,x)*ask(t[o].rs,mid+1,r,x)%p;
    }
    signed main(){
    	n=read();int q=read();
    	REP(i,2,1100){
    		if(!np[i])pr[++pr[0]]=i;
    		REP(j,1,pr[0]){
    			if(1ll*i*pr[j]>1100)break;
    			np[i*pr[j]]=1;
    			if(i%pr[j]==0)break;
    		}
    	}
    	inv[0]=inv[1]=mul[0]=t[0].w=1;
    	REP(i,2,p-1)inv[i]=1ll*(p-p/i)*inv[p%i]%p;
    	REP(i,1,n){
    		int x=read();mul[i]=1ll*mul[i-1]*x%p;rt[i]=rt[i-1];
    		REP(j,1,pr[0]){
    			if(pr[j]*pr[j]>x)break;
    			if(x%pr[j])continue;
    			if(pre[pr[j]])ins(rt[i],1,n,pre[pr[j]],1ll*pr[j]*inv[pr[j]-1]%p);
    			ins(rt[i],1,n,pre[pr[j]]=i,1ll*(pr[j]-1)*inv[pr[j]]%p);
    			do x/=pr[j];while(x%pr[j]==0);
    		}
    		if(x>1){
    			if(pre[x])ins(rt[i],1,n,pre[x],1ll*x*inv[x-1]%p);
    			ins(rt[i],1,n,pre[x]=i,1ll*(x-1)*inv[x]%p);
    		}
    	}
    	int ans=0;
    	while(q--){
    		int l=read()^ans,r=read()^ans;
    		printf("%d
    ",ans=1ll*mul[r]*inv[mul[l-1]]%p*ask(rt[r],1,n,l)%p);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    as3关于正则表达式的那些事
    Flex中使用ArrayCollection的注意事项
    flash资源优化技巧
    测试版权信息
    PHP解密Unicode及Escape加密字符串函数
    php foreach
    硅谷黑暗面:房价过高、政治斗争和岗位侵略
    菜鸟网络股权分配:阿里巴巴占51%的股份
    vue 数据导入加载样式
    CSS文字过多设置省略号
  • 原文地址:https://www.cnblogs.com/HolyK/p/9919206.html
Copyright © 2011-2022 走看看