首先嘛这道题目只要知道一个东西就很容易了:所有循环的最小公约数<=60,成一条链的长度最大为11,那么我们就可以用一个很裸的方法。对于在链上的数,我们修改直接暴力找出并修改。对于在环上的数,我们对每一步建立一颗线段树,那么修改就变成了交换60棵线段树的某个子树。然后我们就可以愉快的写啦~~~

在想的时候被同学坑了,他说最长的循环不超过60.。。。

在实现方面,我用一个map+树状数组维护链上的答案,然后用60棵线段树来维护这个环。懂了之后还是很好写哒~~~

Code:

 #include <cstdio>
#include <cstring>
#include <algorithm> const int N = + , kCycle = + ; int n, m, p, x[N]; int dist[N], cycle = ; inline int GCD(int a, int b) { return b ? GCD(b, a % b) : a; }
inline int LCM(int a, int b) { return a * b / GCD(a, b); } int pre[N]; void Analysis(int a) {
dist[a] = -;
int b = a * a % p;
if (dist[b] == -) {
pre[b] = a;
Analysis(b);
} else if (dist[b] == -) {
int cnt = ;
for (int i = a; i != b; i = pre[i], ++cnt) dist[i] = ;
dist[b] = ;
cycle = LCM(cycle, cnt);
}
if (dist[a] == -) dist[a] = dist[b] + ;
} inline int pos(int l, int r) { return (l + r) | (l != r); } int tree[N * ][kCycle], shift[N * ]; inline void Merge(int u[], int a[], int b[]) {
for (int i = ; i < cycle; ++i) u[i] = a[i] + b[i];
} inline void Shift(int id, int v) {
static int temp[kCycle * ];
(shift[id] += v) %= cycle;
for (int i = ; i < cycle; ++i) temp[i] = tree[id][(i + v) % cycle];
std::copy(temp, temp + cycle, tree[id]);
} void Modify(int l, int r, int u, int v) {
int id = pos(l, r);
for (int i = ; i < cycle; ++i, (v *= v) %= p) tree[id][i] += v;
if (l == r) return;
int mid = (l + r) / ;
if (shift[id]) {
Shift(pos(l, mid), shift[id]);
Shift(pos(mid + , r), shift[id]);
shift[id] = ;
}
if (u <= mid) Modify(l, mid, u, v); else Modify(mid + , r, u, v);
} void Cycle(int l, int r, int u, int v) {
int id = pos(l, r);
if (u <= l && r <= v) {
Shift(id, );
return;
}
int mid = (l + r) / ;
if (shift[id]) {
Shift(pos(l, mid), shift[id]);
Shift(pos(mid + , r), shift[id]);
shift[id] = ;
}
if (u <= mid) Cycle(l, mid, u, v);
if (v > mid) Cycle(mid + , r, u, v);
Merge(tree[id], tree[pos(l, mid)], tree[pos(mid + , r)]);
} int Query(int l, int r, int u, int v) {
int id = pos(l, r);
if (u <= l && r <= v) return tree[id][];
int mid = (l + r) / , res = ;
if (shift[id]) {
Shift(pos(l, mid), shift[id]);
Shift(pos(mid + , r), shift[id]);
shift[id] = ;
}
if (u <= mid) res += Query(l, mid, u, v);
if (v > mid) res += Query(mid + , r, u, v);
return res;
} class BIT {
int data[N]; public:
inline void Add(int p, int v) { for (; p <= n; p += p & -p) data[p] += v; }
inline int Query(int p) {
int res = ;
for (; p; p ^= p & -p) res += data[p];
return res;
}
inline int Query(int l, int r) { return Query(r) - Query(l - ); } } cnt, sum; void Sqr(int l, int r) {
if (!cnt.Query(l, r)) return;
if (l == r) {
cnt.Add(l, -);
sum.Add(l, -x[l]);
if (cnt.Query(l, l) == )
Modify(, n, l, (x[l] *= x[l]) %= p);
else
sum.Add(l, (x[l] *= x[l]) %= p);
} else {
int mid = (l + r) / ;
Sqr(l, mid);
Sqr(mid + , r);
}
} int main() {
scanf("%d%d%d", &n, &m, &p);
for (int i = ; i <= n; ++i) scanf("%d", x + i);
memset(dist, -, sizeof dist);
for (int i = ; i < p; ++i) if (dist[i] == -) Analysis(i);
for (int i = ; i <= n; ++i) {
if (dist[x[i]]) {
sum.Add(i, x[i]);
cnt.Add(i, dist[x[i]]);
} else {
Modify(, n, i, x[i]);
}
}
while (m--) {
int op, l, r;
scanf("%d%d%d", &op, &l, &r);
switch (op) {
case :
Cycle(, n, l, r);
Sqr(l, r);
break;
case :
printf("%d\n", Query(, n, l, r) + sum.Query(l, r));
break;
}
}
return ;
}

4105: [Thu Summer Camp 2015]平方运算的更多相关文章

  1. bzoj:4105: [Thu Summer Camp 2015]平方运算

    Description   Input 第一行有三个整数N,M,p,分别代表序列的长度.平方操作与询问操作的总次数以及在平方操作中所要模的数.   接下来一行N个数代表一开始的序列{X1,X2,... ...

  2. 2018.10.18 bzoj4105: [Thu Summer Camp 2015]平方运算(线段树)

    传送门 线段树妙题. 显然平方几次就会循环(打表证明不解释). 然后所有环长度的lcmlcmlcm不大于70. 因此维护一下当前区间中的节点是否全部在环上. 不是直接暴力到叶子节点修改. 否则整体打标 ...

  3. BZOJ4105 [Thu Summer Camp 2015]平方运算 【线段树】

    题目链接 BZOJ4105 题解 平方操作orz,虽说应该是线段树,但是不会维护啊QAQ 小瞧一眼题解... 平方成环?环长\(lcm\)小于\(60\)? 果然还是打表找规律题.... 那就很好做了 ...

  4. bzoj4105: [Thu Summer Camp 2015]平方运算

    填坑 我不知道怎么算的,但是所有环的LCM数不会超过60 然后用线段树维护这个东西,每个节点记录子树内的循环节 没到循环节的暴力枚举 复杂度是nlogn再乘以循环节长度 #include<cst ...

  5. [Thu Summer Camp 2015]解密运算

    4104: [Thu Summer Camp 2015]解密运算 Time Limit: 10 Sec  Memory Limit: 512 MB Description 对于一个长度为N的字符串,我 ...

  6. 【BZOJ 4104】 4104: [Thu Summer Camp 2015]解密运算 (智商)

    4104: [Thu Summer Camp 2015]解密运算 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 370  Solved: 237 De ...

  7. BZOJ4104:[Thu Summer Camp 2015]解密运算——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4104 对于一个长度为N的字符串,我们在字符串的末尾添加一个特殊的字符".".之 ...

  8. BZOJ4104 [Thu Summer Camp 2015]解密运算 【乱搞】

    题目链接 BZOJ4104 题解 我们将已知字符排序,由循环就可以得到一个对应关系 如样例就是: 0->第5行 1->第1行 1->第2行 1->第3行 1->第5行 2 ...

  9. bzoj 4104 [Thu Summer Camp 2015]解密运算——思路

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4104 想了很久,想出一个 nlogn (也许是 n2logn )的,可惜空间是 n2 . 已 ...

随机推荐

  1. 详解Objective-C的meta-class 分类: ios相关 ios技术 2015-03-07 15:41 51人阅读 评论(0) 收藏

    比较简单的一篇英文,重点是讲解meta-class.翻译下,加深理解. 原文标题:What is a meta-class in Objective-C? 原文地址:http://www.cocoaw ...

  2. PHP大小写问题

    PHP对于系统函数.用户自定义函数.类名称等是不区分大小写的如可以用EHCO也可以用echo调用显示函数, 但对于变量名称又是区分大小写的,如$Name和$NAME是2个不同的变量. 而对于文件名又因 ...

  3. IOS开发-UI学习-sqlite数据库的操作

    IOS开发-UI学习-sqlite数据库的操作 sqlite是一个轻量级的数据库,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了,而且它的处理速度比Mysql.PostgreSQL这 ...

  4. MAC + java 环境配置

    1. 下载安装 jdk 2. 配置环境 2.1. cd到目录 etc/profile 2.2. 使文件可读:chmod 666 profile model 2.3. 添加环境变量,要切换到etc目录: ...

  5. winform - json串的转换

    通过java接口,或者查询数据库返回json串. 可以有两种方式进行解读. 1.简单方式 没有深层结构,最好只有一条数据(当然也可多条).可以用datatable来获取.返回的是clo0.clo1.c ...

  6. JavaWeb:EL & JSTL

    EL:全名为 Expression Language 1.语法:${sessionScope.user.sex}(从Session 的范围中,取得用户的性别), 所有的EL 都是以 ${  为起始,以 ...

  7. (转载)HTML、CSS、JavaScript、PHP、MySQL 的学习顺序是什么?

    文章转载自 鸟巢 - 技术分享的社区 http://t.runoob.com/question/13 1.HTML.CSS.JavaScript 前端学习三部曲,照着这个顺序依次学习 HTML教程.C ...

  8. Cassandra 单机入门例子——有索引

    入门例子: http://wiki.apache.org/cassandra/GettingStarted 添加环境变量并source生效,使得可以在任意位置执行cassandra/bin安装目录下的 ...

  9. 浅谈ServletContext

    ServletContext是什么? WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用.ServletConfig对象中维护了Serv ...

  10. jQuery 鼠标滚轮插件 jquery.mousewheel.js

    jQuery Mousewheel Plugin,用于添加跨浏览器的鼠标滚轮支持.mousewheel事件的处理函数有一点小小的变化,它除了第一个参数event 外,还接收到第二个参数delta.通过 ...