zoukankan      html  css  js  c++  java
  • CF1114F Please, another Queries on Array?

    CF1114F Please, another Queries on Array?

    • 考虑用线段树维护取模后的区间积和真正的区间积所含有的质因子.
    • 每次询问查得这两个值后,一乘一除,即可算出该区间积的欧拉函数.
    • 区间积容易维护,主要考虑如何维护所含的质因子.
    • 注意到 (a_i) 和每次乘的 (x)(leq 300) , 而 (300) 以内的质数恰有 (62) 个,所以可以用一个 (62) 位的非负整数状压表示一个区间所含的质因子,用 (long long) 恰能存下.
    • 注意用 (long long) 状压时需写成 (1LL<<k) .
    • 此题难点在于想到分别维护区间积和质因子,以及用状压记录质因子.
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define mp make_pair
    #define pii pair<int,int>
    inline int read()
    {
    	int x=0;
    	bool pos=1;
    	char ch=getchar();
    	for(;!isdigit(ch);ch=getchar())
    		if(ch=='-')
    			pos=0;
    	for(;isdigit(ch);ch=getchar())
    		x=x*10+ch-'0';
    	return pos?x:-x;
    }
    const int MAXN=4e5+10;
    int prime[MAXN]={2,3,5,7,11,13,17,19,23,29,31,37,41,
    43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,
    127,131,137,139,149,151,157,163,167,173,179,181,191,193,
    197,199,211,223,227,229,233,239,241,251,257,263,269,271,
    277,281,283,293};
    const int siz=62;
    const int P=1e9+7;
    int a[MAXN];
    inline int add(int a,int b)
    {
    	return (a + b) % P;
    }
    inline int mul(int a,int b)
    {
    	return 1LL * a * b % P;
    }
    int fpow(int a,int b)
    {
    	int res=1;
    	while(b)
    		{
    			if(b&1)
    				res=mul(res,a);
    			a=mul(a,a);
    			b>>=1;
    		}
    	return res;
    }
    int inv(int x)
    {
    	return fpow(x,P-2);
    }
    #define root Tree[o]
    #define lson Tree[o<<1]
    #define rson Tree[o<<1|1]
    ll calcdiv(ll x)
    {
    	ll res=0;
    	for(ll i=0;i<siz;++i)
    		if(x%prime[i]==0)
    			res|=(1LL<<i);
    	return res;
    }
    struct node{
    	int l,r;
    	ll div,prod;
    	int tag1;
    	ll tag2;
    	node()
    		{
    			div=0;
    			prod=1;
    			tag1=1;
    			tag2=0;
    		}
    }Tree[MAXN<<2];
    void pushup(int o)
    {
    	root.prod=mul(lson.prod,rson.prod);
    	root.div=lson.div|rson.div;
    }
    void BuildTree(int o,int l,int r)
    {
    	root.l=l,root.r=r;
    	if(l==r)
    		{
    			root.prod=a[l];
    			root.div=calcdiv(a[l]);
    			return;
    		}
    	int mid=(l+r)>>1;
    	BuildTree(o<<1,l,mid);
    	BuildTree(o<<1|1,mid+1,r);
    	pushup(o);
    }
    void Modifiy(int o,int v,ll div)
    {
    	root.tag1=mul(root.tag1,v);
    	root.tag2|=div;
    	root.prod=mul(root.prod,fpow(v,root.r-root.l+1));
    	root.div|=div;
    }
    void pushdown(int o)
    {
    	if(root.tag2==0)
    		return;
    	Modifiy(o<<1,root.tag1,root.tag2);
    	Modifiy(o<<1|1,root.tag1,root.tag2);
    	root.tag1=1;
    	root.tag2=0;
    }
    void update(int o,int L,int R,int v,ll div)
    {
    	int l=root.l,r=root.r;
    	if(l>R || r<L)
    		return;
    	if(L<=l && r<=R)
    		{
    			Modifiy(o,v,div);
    			return;
    		}
    	int mid=(l+r)>>1;
    	pushdown(o);//修改时也要下传标记 
    	if(L<=mid)
    		update(o<<1,L,R,v,div);
    	if(R>mid)
    		update(o<<1|1,L,R,v,div);
    	pushup(o);
    }
    int query(int o,int L,int R,ll &totdiv)
    {
    	int l=root.l,r=root.r;
    	int res=1;
    	if(l>R || r<L)
    		return res;
    	if(L<=l && r<=R)
    		{
    			totdiv|=root.div;
    			return root.prod;	
    		}
    	int mid=(l+r)>>1;
    	pushdown(o);
    	if(L<=mid)
    		res=mul(res,query(o<<1,L,R,totdiv));
    	if(R>mid)
    		res=mul(res,query(o<<1|1,L,R,totdiv));
    	return res;
    }
    int n,m;
    int main()
    {
    //	freopen("data.in","r",stdin);
    //	freopen("data.out","w",stdout);
    	n=read();
    	m=read();
    	for(int i=1;i<=n;++i)
    		a[i]=read();
    	BuildTree(1,1,n);
    	for(int p=1;p<=m;++p)
    		{
    			char buf[10];
    			scanf("%s",buf);
    			if(buf[0]=='M')
    				{
    					int l=read(),r=read(),x=read();
    					ll div=calcdiv(x);
    					update(1,l,r,x,div);
    				}
    			else 
    				{
    					assert(buf[0]=='T');
    					int l=read(),r=read();
    					ll div=0;
    					int prod=query(1,l,r,div);
    					for(ll i=0;i<siz;++i)
    						{
    							if((div>>i)&1LL)
    								prod=mul(prod,prime[i]-1),prod=mul(prod,inv(prime[i]));
    						}
    					printf("%d
    ",prod);
    				}
    		}
    	return 0;
    }
    
  • 相关阅读:
    ZOJ 4097 Rescue the Princess
    最大值最小化 最小值最大化
    SD第九届省赛B题 Bullet
    Euler Circuit UVA
    bzoj 1878
    随笔
    BZOJ
    主席树模板
    AC自动机模板
    BZOJ
  • 原文地址:https://www.cnblogs.com/jklover/p/10388865.html
Copyright © 2011-2022 走看看