Codeforces 1109E. Sasha and a Very Easy Test 线段树
原文链接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 线段树的更多相关文章
- 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. " ...
- Codeforces Round #539 (Div. 1) E - Sasha and a Very Easy Test 线段树
如果mod是质数就好做了,但是做除法的时候对于合数mod可能没有逆元.所以就只有存一下mod的每个质因数(最多9个)的幂,和剩下一坨与mod互质的一部分.然后就能做了.有点恶心. CODE #incl ...
- [Codeforces 464E] The Classic Problem(可持久化线段树)
[Codeforces 464E] The Classic Problem(可持久化线段树) 题面 给出一个带权无向图,每条边的边权是\(2^{x_i}(x_i<10^5)\),求s到t的最短路 ...
- 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 ...
- 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 ...
- 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 ...
- HDU 5475 An easy problem 线段树
An easy problem Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...
- codeforces 893F - Physical Education Lessons 动态开点线段树合并
https://codeforces.com/contest/893/problem/F 题意: 给一个有根树, 多次查询,每次查询对于$x$i点的子树中,距离$x$小于等于$k$的所有点中权值最小的 ...
- Codeforces Round #530 (Div. 2) F (树形dp+线段树)
F. Cookies 链接:http://codeforces.com/contest/1099/problem/F 题意: 给你一棵树,树上有n个节点,每个节点上有ai块饼干,在这个节点上的每块饼干 ...
随机推荐
- Nginx-Tomcat搭建负载均衡(转载)
一. 工具 nginx-1.8.0 apache-tomcat-6.0.33 二. 目标 实现高性能负载均衡的Tomcat集群: 三. 步骤 1.首先下载Nginx,要下载稳定版: 2 ...
- Kubernetes 中的渐进式交付:蓝绿部署和金丝雀部署
渐进式交付是持续交付的下一步, 它将新版本部署到用户的一个子集,并在将其滚动到全部用户之前对其正确性和性能进行评估, 如果不匹配某些关键指标,则进行回滚. 这里有一些有趣的项目,使得渐进式交付在 Ku ...
- [AMD驱动]解决AMD驱动的1603错误
官方:https://www.amd.com/en/support/kb/faq/gpu-kb1603 其实把更改的文档 下载 音乐等默认目录恢复到C盘(或任意一个可访问的路径),就可以正常安装了.
- [PA2014]Druzyny
题目描述 体育课上,n个小朋友排成一行(从1到n编号),老师想把他们分成若干组,每一组都包含编号连续的一段小朋友,每个小朋友属于且仅属于一个组.第i个小朋友希望它所在的组的人数不多于d[i],不少于c ...
- 洛谷P3369 普通平衡树
刚学平衡树,分别用了Splay和fhq-treap交了一遍. 这是Splay的板子,貌似比较短? Splay #include <iostream> #include <cstdio ...
- expansion pattern ‘Frame&’ contains no argument packs
camera/CameraImpl.h::: error: expansion pattern ‘Frame&’ contains no argument packs void read_fr ...
- kubernetes云平台管理实战: 故障自愈实战(四)
一.创建实验文件 [root@k8s-master ~]# cat myweb-rc.yml apiVersion: v1 kind: ReplicationController metadata: ...
- 第四节: Quartz.Net五大构件之Trigger通用用法(常用方法、优先级、与job关联等)
一. 简介 1. 几个类型: ①:TriggerBuilder:用来创建ITrigger实例 ②:ITrigger:触发器实例 2.常用的几个方法 ①.StartNow:Trigger马上触发. ②. ...
- Beamer中左边画图, 右边文字解释
\begin{columns} \column{.4\textwidth} \begin{figure} \centering % Requires \usepackage{graphicx} \in ...
- Codeforces Round #501 (Div. 3) D. Walking Between Houses
题目链接 题意:给你三个数n,k,sn,k,sn,k,s,让你构造一个长度为k的数列,使得相邻两项差值的绝对值之和为sss, ∑i=1n∣a[i]−a[i−1]∣,a[0]=1\sum_{i=1}^n ...