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

题意

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

要求支持 q 次以下操作:

区间乘

单点除(保证能够整除)

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

$$n,q\leq 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\n",Query(1,1,n,a,b));
}
}
return 0;
}

  

Codeforces 1109E. Sasha and a Very Easy Test 线段树的更多相关文章

  1. CodeForces 1109E. Sasha and a Very Easy Test

    题目简述:给定$m \leq 10^9+9$,维护以下操作 1. "1 l r x":将序列$a[l], a[l+1], \dots, a[r]$都乘上$x$. 2. " ...

  2. Codeforces Round #539 (Div. 1) E - Sasha and a Very Easy Test 线段树

    如果mod是质数就好做了,但是做除法的时候对于合数mod可能没有逆元.所以就只有存一下mod的每个质因数(最多9个)的幂,和剩下一坨与mod互质的一部分.然后就能做了.有点恶心. CODE #incl ...

  3. [Codeforces 464E] The Classic Problem(可持久化线段树)

    [Codeforces 464E] The Classic Problem(可持久化线段树) 题面 给出一个带权无向图,每条边的边权是\(2^{x_i}(x_i<10^5)\),求s到t的最短路 ...

  4. Codeforces Round #373 (Div. 2) E. Sasha and Array 矩阵快速幂+线段树

    E. Sasha and Array time limit per test 5 seconds memory limit per test 256 megabytes input standard ...

  5. Educational Codeforces Round 6 E. New Year Tree dfs+线段树

    题目链接:http://codeforces.com/contest/620/problem/E E. New Year Tree time limit per test 3 seconds memo ...

  6. Codeforces Round #244 (Div. 2) B. Prison Transfer 线段树rmq

    B. Prison Transfer Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/pro ...

  7. HDU 5475 An easy problem 线段树

    An easy problem Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...

  8. codeforces 893F - Physical Education Lessons 动态开点线段树合并

    https://codeforces.com/contest/893/problem/F 题意: 给一个有根树, 多次查询,每次查询对于$x$i点的子树中,距离$x$小于等于$k$的所有点中权值最小的 ...

  9. Codeforces Round #530 (Div. 2) F (树形dp+线段树)

    F. Cookies 链接:http://codeforces.com/contest/1099/problem/F 题意: 给你一棵树,树上有n个节点,每个节点上有ai块饼干,在这个节点上的每块饼干 ...

随机推荐

  1. python之旅九【第九篇】socket

    什么是socket 建立网络通信连接至少要一对端口号(socket).socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket ...

  2. Android学习第十天

    计算机表示图形的几种方式 a)         Bmp:以高质量保存,用于计算机 b)         Jpg:以良好的质量保存,用于计算机或网络 c)         Png:以高质量保存 d)   ...

  3. 【XSY2925】cti 网络流

    题目描述 有一个 \(n\times m\)的网格,每个格子里面可能有一些炮塔,或者有几个人. 每个炮塔可以在给定的方向(上下左右)上选一个点作为它的攻击位置,然后消灭这个格子里面的所有人.当然也可以 ...

  4. XUGUO-书呆子-搜索书箱

    WorldCat 上的 米塔斯 通过图书馆馆藏的全球目录WorldCat,在附近的图书馆中查找所要的资料. < 用 Sketch 创作 Airiti Library華藝線上圖書館 BookBub ...

  5. Django 2.0.4 微博第三方登录

    三方登录逻辑 理解第三方登录的流程: 用户向本地应用商城发起请求,我要用微博进行登录 我们的商城凑一个url让用户跳转到第三方应用的url(微博的登录页面) 用户在该界面点击输入用户名密码之后,点击授 ...

  6. 一个select元素自定义设计的新思路:appearance: none之后利用<>符号制造小箭头

    最近工作时解决了一个前端小问题(如下图所示):在Safari中,select的控件之上有不和谐的灰色部分. 刚开始时我以为是backgrand或是border设置不当之类产生的问题,在搜索了很久之后终 ...

  7. NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions

    .NET Core 控制台程序没有 ASP.NET Core 的 IWebHostBuilder 与 Startup.cs ,那要读 appsettings.json.注依赖.配日志.设 IOptio ...

  8. tolua之wrap文件的原理与使用

    什么是wrap文件 每个wrap文件都是对一个c#类的包装,在lua中,通过对wrap类中的函数调用,间接的对c#实例进行操作. wrap类文件生成和使用的总体流程 生成一个wrap文件的流程 这部分 ...

  9. 第四节: EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法

    一. 背景 上一个章节,介绍了EF调用两类SQL语句,主要是借助 ExecuteSqlCommand  和 SqlQuery 两个方法来完成,在本章节主要是复习几类存储过程的写法和对应的EF调用这几类 ...

  10. 第十一节: EF的三种模式(一) 之 DBFirst模式(SQLServer和MySQL两套方案)

    一. 简介 EF连接数据库有三种模式,分别是DBFirst.ModelFirst.CodeFirst,分别适用于不同的开发场景. 该章节,将主要介绍EF的DBFirst连接SQLServer数据库和M ...