Sasha and a Very Easy Test CodeForces - 1109E (数学,线段树)
大意: 给定n元素序列, q个操作: (1)区间乘 (2)单点除(保证整除) (3)区间求和对m取模
要求回答所有操作(3)的结果
主要是除法难办, 假设单点除$x$, $x$中与$m$互素的素因子可以直接欧拉求逆, 其余因子维护一个向量即可.
这种沙茶题结果各种细节出错改了一个多小时......太菜了
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <math.h>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <string.h>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define hr putchar(10)
#define pb push_back
#define lc (o<<1)
#define rc (lc|1)
#define mid ((l+r)>>1)
#define ls lc,l,mid
#define rs rc,mid+1,r
#define x first
#define y second
#define io std::ios::sync_with_stdio(false)
#define endl '\n'
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int P = 1e9+7, INF = 0x3f3f3f3f;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
//head const int N = 1e5+10; int n, m, q, sz, Phi;
vector<int> A; int phi(int x) {
int s = x, mx = sqrt(x+0.5);
REP(i,2,mx) if (x%i==0) {
s = s/i*(i-1);
A.pb(i);
while (x%i==0) x/=i;
}
if (x>1) A.pb(x),s=s/x*(x-1);
sz = A.size();
return s;
} ll qpow(ll a,ll n) {ll r=1%m;for (a%=m;n;a=a*a%m,n>>=1)if(n&1)r=r*a%m;return r;} int sum[N<<2], rtag[N<<2], tag[N<<2], res[N<<2];
int c[N<<2][10], tagc[N<<2][10];
int ans, ql, qr, qv[10]; void pd(int o) {
if (tag[o]!=1) {
tag[lc] = (ll)tag[lc]*tag[o]%m;
tag[rc] = (ll)tag[rc]*tag[o]%m;
sum[lc] = (ll)sum[lc]*tag[o]%m;
sum[rc] = (ll)sum[rc]*tag[o]%m;
tag[o] = 1;
}
if (rtag[o]!=1) {
res[lc] = (ll)res[lc]*rtag[o]%m;
res[rc] = (ll)res[rc]*rtag[o]%m;
rtag[lc] = (ll)rtag[lc]*rtag[o]%m;
rtag[rc] = (ll)rtag[rc]*rtag[o]%m;
rtag[o] = 1;
}
REP(i,0,sz-1) {
c[lc][i]+=tagc[o][i],c[rc][i]+=tagc[o][i];
tagc[lc][i]+=tagc[o][i],tagc[rc][i]+=tagc[o][i];
tagc[o][i]=0;
}
} void pu(int o) {
sum[o]=(sum[rc]+sum[lc])%m;
} void build(int o, int l, int r) {
sum[o]=res[o]=tag[o]=rtag[o]=1;
if (l==r) {
int t;
scanf("%d", &t);
sum[o] = t%m;
REP(i,0,sz-1) {
while (t%A[i]==0) t/=A[i],++c[o][i];
}
res[o] = t%m;
return;
}
build(ls),build(rs);
pu(o);
} void mul(int o, int l, int r, int x, int R) {
if (ql<=l&&r<=qr) {
sum[o] = (ll)sum[o]*x%m;
tag[o] = (ll)tag[o]*x%m;
res[o] = (ll)res[o]*R%m;
rtag[o] = (ll)rtag[o]*R%m;
REP(i,0,sz-1) c[o][i]+=qv[i],tagc[o][i]+=qv[i];
return;
}
pd(o);
if (mid>=ql) mul(ls,x,R);
if (mid<qr) mul(rs,x,R);
pu(o);
}
void div(int o, int l, int r, int x, int v) {
if (l==r) {
REP(i,0,sz-1) {
while (v%A[i]==0) v/=A[i],--c[o][i];
}
res[o] = (ll)res[o]*qpow(v,Phi-1)%m;
sum[o] = res[o];
REP(i,0,sz-1) sum[o]=(ll)sum[o]*qpow(A[i],c[o][i])%m;
return;
}
pd(o);
if (mid>=x) div(ls,x,v);
else div(rs,x,v);
pu(o);
}
void query(int o, int l, int r, int ql, int qr) {
if (ql<=l&&r<=qr) return (ans+=sum[o])%=m,void();
pd(o);
if (mid>=ql) query(ls,ql,qr);
if (mid<qr) query(rs,ql,qr);
} int main() {
scanf("%d%d", &n, &m);
Phi = phi(m);
build(1,1,n);
scanf("%d", &q);
while (q--) {
int op, x, p;
scanf("%d", &op);
if (op==1) {
scanf("%d%d%d",&ql,&qr,&x);
int t = x;
REP(i,0,sz-1) {
qv[i] = 0;
while (t%A[i]==0) t/=A[i],++qv[i];
}
mul(1,1,n,x,t);
} else if (op==2) {
scanf("%d%d",&p,&x);
div(1,1,n,p,x);
} else {
scanf("%d%d",&ql,&qr);
ans = 0, query(1,1,n,ql,qr);
printf("%d\n", ans);
}
}
}
Sasha and a Very Easy Test CodeForces - 1109E (数学,线段树)的更多相关文章
- Vasya and a Tree CodeForces - 1076E(线段树+dfs)
I - Vasya and a Tree CodeForces - 1076E 其实参考完别人的思路,写完程序交上去,还是没理解啥意思..昨晚再仔细想了想.终于弄明白了(有可能不对 题意是有一棵树n个 ...
- Codeforces 787D. Legacy 线段树建模+最短路
D. Legacy time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...
- Almost Regular Bracket Sequence CodeForces - 1095E (线段树,单点更新,区间查询维护括号序列)
Almost Regular Bracket Sequence CodeForces - 1095E You are given a bracket sequence ss consisting of ...
- Sereja and Brackets CodeForces - 380C (线段树+分治思路)
Sereja and Brackets 题目链接: CodeForces - 380C Sereja has a bracket sequence s1, s2, ..., *s**n, or, in ...
- CodeForces 91B Queue (线段树,区间最值)
http://codeforces.com/problemset/problem/91/B B. Queue time limit per test: 2 seconds memory limit p ...
- codeforces 650D. Zip-line 线段树
题目链接 题目的意思很简单, 就是给你n个数, m个询问, 每次询问修改某一个位置的值, 然后问你修改完之后数列的lis是多少. 询问独立. 对于原数列, 我们将它离散化, 令dp1[i]为以i为结尾 ...
- Codeforces 343D WaterTree - 线段树, DFS序
Description Translated by @Nishikino_Maki from Luogu 行吧是我翻的 Mad scientist Mike has constructed a roo ...
- codeforces 787D - Legacy 线段树优化建图,最短路
题意: 有n个点,q个询问, 每次询问有一种操作. 操作1:u→[l,r](即u到l,l+1,l+2,...,r距离均为w)的距离为w: 操作2:[l,r]→u的距离为w 操作3:u到v的距离为w 最 ...
- Subtree Minimum Query CodeForces - 893F (线段树合并+线段树动态开点)
题目链接:https://cn.vjudge.net/problem/CodeForces-893F 题目大意:给你n个点,每一个点有权值,然后这n个点会构成一棵树,边权为1.然后有q次询问,每一次询 ...
随机推荐
- LINUX环境变量(二)
一.Shell变量分为本地变量和环境变量. 1.本地变量:在用户现有运行的脚本中使用 a) 定义本地变量 格式: variable-name=value b) 显示本地变量 格式: set c) 清 ...
- Shell脚本实现每个工作日定时执行指定程序
我们可能会遇到这样的情景:必须在每个工作日定时执行Linux服务器上的某个程序.那么有没有办法实现这一功能呢?答案是肯定的.我们可以运用Shell脚本简单实现这一功能. 原理很简单,Shell脚本内部 ...
- python-随机数的产生random模块
random模块用来产生随机数: 查看random模块的方法: import random random.__dir__ Out[39]: <function __dir__> rando ...
- Python Web学习笔记之递归和迭代的区别
电影故事例证:迭代——<明日边缘>递归——<盗梦空间> 迭代是更新变量的旧值.递归是在函数内部调用自身. 迭代是将输出做为输入,再次进行处理.比如将摄像头对着显示器:比如镜子对 ...
- 01: 企业微信API开发前准备
目录:企业微信API其他篇 01: 企业微信API开发前准备 02:消息推送 03: 通讯录管理 04:应用管理 目录: 1.1 术语介绍 1.2 开发步骤 1.1 术语介绍返回顶部 参考文档:htt ...
- 20145304 Exp9 Web安全基础实践
20145304 Exp9 Web安全基础实践 实验后回答问题 (1)SQL注入攻击原理,如何防御 SQL注入是将查询语句当做查询内容输入到查询的框中,以此来使服务器执行攻击者想让它执行的语句,而不是 ...
- 20165211 2017-2018-2 《Java程序设计》第3周学习总结
20165211 2017-2018-2 <Java程序设计>第3周学习总结 教材学习内容总结 本周,我学习了书本上第四章的内容,以下是我整理的主要知识. 第四章 类与对象 编程语言的几个 ...
- 2018-2019-1 1723《程序设计与数据结构》第1&2周作业 总结
作业地址 第一周作业: https://edu.cnblogs.com/campus/besti/CS-IMIS-1723-2/homework/2092 提交情况如图: 第二周作业: https:/ ...
- __NSCFConstantString && __NSPlaceholderDictionary
一 -[__NSCFConstantString size]: unrecognized selector sent to instance 0x53ea70 该错误是在我将NSString类型的参数 ...
- 51nod 1050 循环数组最大子段和 单调队列优化DP
题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1050 这个呢,这个题之前 求一遍最大值 然后求一遍最小值 ...