zoukankan      html  css  js  c++  java
  • Codeforces 1109E. Sasha and a Very Easy Test 线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF1109E.html

    题意

    给定一个长度为 n 的数列 a,以及一个模数 M(不一定是质数)。

    要求支持 q 次以下操作:

    区间乘

    单点除(保证能够整除)

    区间求和,最终结果对 M 取模输出。

    $$n,qleq 10^5$$

    题解

    这里我们设 $f(x)$ 表示 $frac x {gcd(x,M)}$ 。

    令 $c(x,i)$ 表示 x 最多能够整除 M 的第 $i$ 个质因子的 $c(x,i)$ 次方。

    线段树维护一下单点 $f(x)$ 值,以及所有单点 $c(x,i)$;再维护一下所有区间和就好了。

    暴写一通,注意取模。这题为什么会放E……

    代码

    #include <bits/stdc++.h>
    #define clr(x) memset(x,0,sizeof (x))
    using namespace std;
    typedef long long LL;
    LL read(){
    	LL x=0,f=0;
    	char ch=getchar();
    	while (!isdigit(ch))
    		f|=ch=='-',ch=getchar();
    	while (isdigit(ch))
    		x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    	return f?-x:x;
    }
    const int N=100005;
    int n,mod,phi;
    int a[N];
    vector <int> fenjie(int n){
    	static vector <int> ans;
    	ans.clear();
    	for (int i=2;i*i<=n;i++)
    		while (n%i==0)
    			n/=i,ans.push_back(i);
    	if (n>1)
    		ans.push_back(n);
    	return ans;
    }
    void Unique(vector <int> &v){
    	sort(v.begin(),v.end());
    	int u=unique(v.begin(),v.end())-v.begin();
    	while (v.size()>u)
    		v.pop_back();
    }
    int Phi(int n){
    	int ans=n;
    	for (int i=2;i*i<=n;i++)
    		if (n%i==0){
    			ans=ans/i*(i-1);
    			while (n%i==0)
    				n/=i;
    		}
    	if (n>1)
    		ans=ans/n*(n-1);
    	return ans;
    }
    int Pow(int x,int y,int mod=::mod){
    	int ans=1;
    	for (;y;y>>=1,x=(LL)x*x%mod)
    		if (y&1)
    			ans=(LL)ans*x%mod;
    	return ans;
    }
    int Inv(int x){
    	return Pow(x,phi-1);
    }
    vector <int> pm;
    const int S=40;
    int pcnt;
    int ti[N<<2][S],val[N<<2],add[N<<2],nad[N<<2];
    void pushdown(int rt){
    	int ls=rt<<1,rs=ls|1;	
    	for (int i=1;i<=pcnt;i++){
    		ti[ls][i]+=ti[rt][i];
    		ti[rs][i]+=ti[rt][i];
    		ti[rt][i]=0;
    	}
    	val[ls]=(LL)val[ls]*add[rt]%mod;
    	val[rs]=(LL)val[rs]*add[rt]%mod;
    	add[ls]=(LL)add[ls]*add[rt]%mod;
    	add[rs]=(LL)add[rs]*add[rt]%mod;
    	add[rt]=1;
    	nad[ls]=(LL)nad[ls]*nad[rt]%mod;
    	nad[rs]=(LL)nad[rs]*nad[rt]%mod;
    	nad[rt]=1;
    }
    void pushup(int rt){
    	val[rt]=(val[rt<<1]+val[rt<<1|1])%mod;
    }
    void Get(int v,int &ans,int *c){
    	for (int i=1;i<=pcnt;i++)
    		while (v%pm[i-1]==0)
    			v/=pm[i-1],c[i]++;
    	ans=v%mod;
    }
    void build(int rt,int L,int R){
    	add[rt]=nad[rt]=1,clr(ti[rt]);
    	if (L==R){
    		val[rt]=a[L]%mod;
    		Get(a[L],nad[rt],ti[rt]);
    		return;
    	}
    	int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
    	build(ls,L,mid);
    	build(rs,mid+1,R);
    	pushup(rt);
    }
    void update1(int rt,int L,int R,int xL,int xR,int v,int *d,int nv){
    	if (R<xL||L>xR)
    		return;
    	if (xL<=L&&R<=xR){
    		for (int i=1;i<=pcnt;i++)
    			ti[rt][i]+=d[i];
    		val[rt]=(LL)val[rt]*v%mod;
    		add[rt]=(LL)add[rt]*v%mod;
    		nad[rt]=(LL)nad[rt]*nv%mod;
    		return;
    	}
    	pushdown(rt);
    	int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
    	update1(ls,L,mid,xL,xR,v,d,nv);
    	update1(rs,mid+1,R,xL,xR,v,d,nv);
    	pushup(rt);
    }
    int Calc(int v,int *c){
    	for (int i=1;i<=pcnt;i++)
    		v=(LL)v*Pow(pm[i-1],c[i])%mod;
    	return v;
    }
    void update2(int rt,int L,int R,int x,int v,int *d,int nv){
    	if (L==R){
    		nad[rt]=(LL)nad[rt]*Inv(nv)%mod;
    		for (int i=1;i<=pcnt;i++)
    			ti[rt][i]-=d[i];
    		val[rt]=Calc(nad[rt],ti[rt]);
    		return;
    	}
    	pushdown(rt);
    	int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
    	if (x<=mid)
    		update2(ls,L,mid,x,v,d,nv);
    	else
    		update2(rs,mid+1,R,x,v,d,nv);
    	pushup(rt);
    }
    int Query(int rt,int L,int R,int xL,int xR){
    	if (R<xL||L>xR)
    		return 0;
    	if (xL<=L&&R<=xR)
    		return val[rt];
    	pushdown(rt);
    	int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
    	return (Query(ls,L,mid,xL,xR)+Query(rs,mid+1,R,xL,xR))%mod;
    }
    int main(){
    	n=read(),mod=read(),phi=Phi(mod);
    	for (int i=1;i<=n;i++)
    		a[i]=read();
    	pm=fenjie(mod);
    	Unique(pm);
    	pcnt=pm.size();
    	build(1,1,n);
    	int q=read();
    	while (q--){
    		static int cc[S];
    		int type=read(),a=read(),b=read();
    		clr(cc);
    		if (type==1){
    			int x=read(),v;
    			Get(x,v,cc);
    			update1(1,1,n,a,b,x,cc,v);
    		}
    		else if (type==2){
    			int v;
    			Get(b,v,cc);
    			update2(1,1,n,a,b,cc,v);
    		}
    		else {
    			printf("%d
    ",Query(1,1,n,a,b));
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    AngularJS 1.x系列:AngularJS过滤器(4)
    AngularJS 1.x系列:AngularJS控制器(3)
    AngularJS 1.x系列:AngularJS简介及第一个应用(2)
    AngularJS 1.x系列:Node.js安装及npm常用命令(1)
    MySQL系列:索引基本操作(4)
    基于 Mathematica 的机器人仿真环境(机械臂篇)[转]
    使用耳切法将多边形三角化【转】
    asp.net调用非托管dll,无法加载 DLL,找不到指定模块解决方法。【转】
    ASP.NET与非托管DLL的那些事儿【转+增】
    cesium常用设置【转】
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/CF1109E.html
Copyright © 2011-2022 走看看