zoukankan      html  css  js  c++  java
  • [codeforces]Round #538 (Div. 2) F. Please, another Queries on Array?

    题解: 

         $$  ans=Fleft ( prod _{i=l}^{r}a_i ight ) $$

       $$ =(p_i-1){p_i}^{k_i-1}*.....*(p_j-1){p_j}^{k_j-1} $$

       $$={p_i}^{k_i}*.....*{p_j}^{k_j}*(frac{p_i-1}{p_i}*......*frac{p_j-1}{p_j})  $$

       因为数据范围保证$ a_ileq 300 $ 所以在这个范围内只有62个素因子  我们可以直接每一位对应一bit  来判断区间中某个素因子是否出现 然后查询就行了

    (常数写的有点大....懒得优化了  

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <set>
    #include <map>
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define link(x) for(edge *j=h[x];j;j=j->next)
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=4e5+10;
    const double eps=1e-8;
    #define ll long long
    const int mod=1e9+7;
    using namespace std;
    struct edge{int t,v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
    void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;}
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    
    ll ksm(ll a,ll b){
        ll ans=1;
        while(b){
    	if(b&1)ans=ans*a%mod;
    	a=a*a%mod;b=b>>1;
        }
        return ans;
    }
    
    ll key[MAXN<<2],tag[MAXN<<2],sum[MAXN<<2],flag[MAXN<<2];
    int a[MAXN];
    int vis[305],p[MAXN];
    
    void push(int rt,int l,int r){
        if(tag[rt]!=1){
    	int mid=(l+r)>>1;
    	tag[rt<<1]*=tag[rt];tag[rt<<1]%=mod;
    	tag[rt<<1|1]*=tag[rt];tag[rt<<1|1]%=mod;
    	sum[rt<<1]*=ksm(tag[rt],mid-l+1);sum[rt<<1]%=mod;
    	sum[rt<<1|1]*=ksm(tag[rt],r-mid);sum[rt<<1|1]%=mod;
    	tag[rt]=1;
        }
        if(flag[rt]){
    	key[rt<<1]|=flag[rt];key[rt<<1|1]|=flag[rt];
    	flag[rt<<1]|=flag[rt];flag[rt<<1|1]|=flag[rt];
    	flag[rt]=0;
        }
    }
    
    
    void up(int x){
        key[x]=(key[x<<1]|key[x<<1|1]);
        sum[x]=(sum[x<<1]*sum[x<<1|1])%mod;
    }
    
    void built(int rt,int l,int r){
        tag[rt]=1;
        if(l==r){
    	sum[rt]=1;
    	for(int i=2;i*i<=a[l];i++){
    	    if(a[l]%i==0){
    		int num=0;
    		while(a[l]%i==0)num++,a[l]/=i;
    		sum[rt]=sum[rt]*ksm(i,num)%mod;
    		key[rt]|=(1LL<<vis[i]);
    	    }
    	}
    	if(a[l]!=1){
    	    sum[rt]=(sum[rt]*a[l])%mod;
    	    key[rt]|=(1LL<<vis[a[l]]);
    	}
    	return ;
        }
        int mid=(l+r)>>1;
        built(rt<<1,l,mid);
        built(rt<<1|1,mid+1,r);
        up(rt);
    }
    
    ll v1,v2;
    
    void update(int rt,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr){
    	tag[rt]*=v1;tag[rt]%=mod;flag[rt]|=v2;
    	sum[rt]*=ksm(v1,r-l+1);key[rt]|=v2;
    	return ;
        }
        int mid=(l+r)>>1;
        push(rt,l,r);
        if(ql<=mid)update(rt<<1,l,mid,ql,qr);
        if(qr>mid)update(rt<<1|1,mid+1,r,ql,qr);
        up(rt);
    }
    
    ll ans1,ans2;
    void query(int rt,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr){
    	ans1*=sum[rt];ans1%=mod;ans2|=key[rt];
    	return ;
        }
        int mid=(l+r)>>1;
        push(rt,l,r);
        if(ql<=mid)query(rt<<1,l,mid,ql,qr);
        if(qr>mid)query(rt<<1|1,mid+1,r,ql,qr);
        up(rt);
    }
    
    int main(){
        int cnt=0;
        inc(i,2,300){
    	bool flag=0;
    	for(int j=2;j*j<=i;j++){
    	    if(i%j==0){flag=1;break;}
    	}
    	if(!flag)vis[i]=cnt++,p[cnt-1]=i;
        }
        int n=read();int m=read();
        inc(i,1,n)a[i]=read();
        built(1,1,n);
        char str[11];int l,r,x;
        while(m--){
    	scanf("%s",str);
    	l=read();r=read();
    	if(str[0]=='T'){
    	    ans1=1;ans2=0;query(1,1,n,l,r);
    	    for(int i=61;i>=0;i--){
    		if((ans2>>i)&1)ans1*=((p[i]-1)*ksm(p[i],mod-2)%mod),ans1%=mod;
    	    }
    	    printf("%lld
    ",ans1);
    	}
    	else{
    	    x=read();
    	    v1=1;v2=0;
    	    for(int i=2;i*i<=x;i++){
    		    if(x%i==0){
    		    int num=0;
    			while(x%i==0)num++,x/=i;
    			v1=v1*ksm(i,num)%mod;
    			v2|=(1LL<<vis[i]);
    		}
    	    }
    	    if(x!=1){
    		v1=(v1*x)%mod;
    		v2|=(1LL<<vis[x]);
    	    }
    	    update(1,1,n,l,r);
    	}
        }
        return 0;
    }
    

      

  • 相关阅读:
    js正则表达式基本语法
    类似于QQ的右滑删除效果的实现方法
    JS设置cookie、读取cookie、删除cookie
    JavaScript随机生成颜色的方法
    mysql数据库备份及恢复
    Javascript 实现简单计算器实例代码
    JavaScript 实现的checkbox经典实例分享
    网页瀑布流布局jQuery实现代码
    Django Web在Apache上的部署
    VIM使用系列之一——配置VIM下C/C++编程环境
  • 原文地址:https://www.cnblogs.com/wang9897/p/10360754.html
Copyright © 2011-2022 走看看