题目描述

巨酱有 n 副耳机,他把它们摆成了一列,并且由 1 到n依次编号。每个耳机有一个玄学值,反映了各自的一些不可名状的独特性能。玄学值都是 0 到 m-1 间的整数。在外界的作用下(包括但不限于换线、上放、更换电源为核电、让kAc叔叔给它们讲故事),这些耳机的玄学值会发生改变。特别地,巨酱观察发现,每种作用 o 对应了两个整数 ao与 bo,在这种作用之后,玄学值原本为 x 的耳机,其玄学值恰会变成 (aox+bo)modm。

巨酱对他手头耳机的表现并不满意,遗憾的是,最近他并不有钱,无法任性,不能赶紧买买买以满足自己。手头紧张的他准备拟定一个相对经济的方案,通过各种作用来改善他手头玩具的性能。具体地说,为了尽快完成方案的制订,巨酱希望自己能高效地完成以下工作:

巨酱想到了一种操作,能让耳机的玄学值由 x 变为 (ax+b)modm,并且他计划对编号为 i 到 j 的耳机执行这种操作。
巨酱想知道如果将(并且仅将)自己的第 i 个到第 j 个计划按顺序付诸行动,编号为 k 的耳机的玄学值将会变成多少。
出于著名算法竞赛选手的矜持,巨酱表示自己才不需要你的帮助。但是如果巨酱真的厌倦了自己的玩具,它们就会被50包邮出给主席。为了不让后者白白捡到便宜,你考虑再三还是决定出手。

题解

二进制分组的思想。

用线段树维护时间的操作序列,每次操作一个一个往线段树里面插,等到一个线段被插满的时候用归并来维护区间的信息。查询的时候如果一个线段没有被插满就递归下去。定位到一个区间的时候在区间里面归并出来的信息二分。

代码

 #include <cstdio>

 #define maxn 100010
#define maxm 600010
#define R register
int x[maxn], tnum;
struct Seg {
int l, r, a, b;
} p[maxn * ];
int lef[maxm << ], rig[maxm << ], pcnt, ta, tb, ql, qr, n, m, k, ans;
void update(R int o, R int l, R int r)
{
lef[o] = pcnt + ;
for (R int i = lef[o << ], j = lef[o << | ], head = ; i <= rig[o << ] || j <= rig[o << | ]; )
if (p[i].r <= p[j].r)
{
p[++pcnt] = (Seg) {head, p[i].r, 1ll * p[i].a * p[j].a % m, (1ll * p[j].a * p[i].b + p[j].b) % m};
head = p[i].r + ;
p[i].r == p[j].r ? ++j : ; ++i;
}
else
{
p[++pcnt] = (Seg) {head, p[j].r, 1ll * p[i].a * p[j].a % m, (1ll * p[j].a * p[i].b + p[j].b) % m};
head = p[j].r + ; ++j;
}
rig[o] = pcnt;
}
int find(R int o, R int t, R int &s)
{
R int l = lef[o], r = rig[o];
while (l < r)
{
R int mid = l + r >> ;
if (t <= p[mid].r) r = mid;
else l = mid + ;
}
// printf("%d %d t %d s %d %d %d\n", p[l].l, p[l].r, t, s, p[l].a, p[l].b);
s = (1ll * s * p[l].a + p[l].b) % m;
}
void modify(R int o, R int l, R int r, R int t)
{
if (l == r)
{
lef[o] = pcnt + ;
ql > ? p[++pcnt] = (Seg) {, ql - , , }, : ;
p[++pcnt] = (Seg) {ql, qr, ta, tb};
qr < n ? p[++pcnt] = (Seg) {qr + , n, , }, : ;
rig[o] = pcnt;
return ;
}
R int mid = l + r >> ;
if (t <= mid) modify(o << , l, mid, t);
else modify(o << | , mid + , r, t); if (t == r) update(o, l, r);
}
void query(R int o, R int l, R int r)
{
if (ql <= l && r <= qr)
{
find(o, k, ans);
return ;
}
R int mid = l + r >> ;
if (ql <= mid) query(o << , l, mid);
if (mid < qr) query(o << | , mid + , r);
}
int main()
{
R int type; scanf("%d%d%d", &type, &n, &m);
for (R int i = ; i <= n; ++i) scanf("%d", &x[i]);
R int Q; scanf("%d", &Q);
for (R int QQ = ; QQ <= Q; ++QQ)
{
R int opt, l, r; scanf("%d%d%d", &opt, &l, &r);
type & ? l ^= ans, r ^= ans : ;
if (opt == )
{
scanf("%d%d", &ta, &tb); ++tnum; ql = l; qr = r;
modify(, , Q, tnum);
}
else
{
scanf("%d", &k); type & ? k ^= ans : ; ql = l; qr = r;
ans = x[k];
query(, , Q);
printf("%d\n", ans);
}
}
return ;
}

【UOJ #46】 【清华集训2014】玄学的更多相关文章

  1. uoj #46[清华集训2014]玄学

    uoj 因为询问是关于一段连续区间内的操作的,所以对操作构建线段树,这里每个点维护若干个不交的区间,每个区间\((l,r,a,b)\)表示区间\([l,r]\)内的数要变成\(ax+b\) 每次把新操 ...

  2. 【uoj#46】 [清华集训2014] 玄学

      题目传送门:uoj46   题意简述:要求在序列上维护一个操作间支持结合律的区间操作,查询连续一段时间内的操作对单点的作用效果,\(n \leq 10^5,m \leq 6 \times 10^5 ...

  3. [UOJ46][清华集训2014]玄学

    uoj description 给出\(n\)个变换,第\(i\)个变换是将区间中\(l_i,r_i\)的数\(x\)变成\((a_ix+b_i)\mod m\). 每次会新增一个变换,或者查询询问如 ...

  4. UOJ.41.[清华集训2014]矩阵变换(稳定婚姻)

    题目链接 稳定婚姻问题:有n个男生n个女生,每个男/女生对每个女/男生有一个不同的喜爱程度.给每个人选择配偶. 若不存在 x,y未匹配,且x喜欢y胜过喜欢x当前的配偶,y喜欢x也胜过y当前的配偶 的完 ...

  5. bzoj 3816&&uoj #41. [清华集训2014]矩阵变换

    稳定婚姻问题: 有n个男生,n个女生,所有女生在每个男生眼里有个排名,反之一样. 将男生和女生两两配对,保证不会出现婚姻不稳定的问题. 即A-1,B-2 而A更喜欢2,2更喜欢A. 算法流程: 每次男 ...

  6. UOJ46 清华集训2014玄学(线段树)

    注意到操作有结合律,容易想到用一个矩形表示第i次操作对第j个位置的数的影响.那么修改是单行内的区间修改,而查询是单列内的区间查询.这样二维线段树上以列为外层行为内层直接打标记就可以维护.然后就喜闻乐见 ...

  7. uoj 41 【清华集训2014】矩阵变换 婚姻稳定问题

    [清华集训2014]矩阵变换 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/41 Description 给出 ...

  8. AC日记——【清华集训2014】奇数国 uoj 38

    #38. [清华集训2014]奇数国 思路: 题目中的number与product不想冲: 即为number与product互素: 所以,求phi(product)即可: 除一个数等同于在模的意义下乘 ...

  9. [UOJ#274][清华集训2016]温暖会指引我们前行

    [UOJ#274][清华集训2016]温暖会指引我们前行 试题描述 寒冬又一次肆虐了北国大地 无情的北风穿透了人们御寒的衣物 可怜虫们在冬夜中发出无助的哀嚎 “冻死宝宝了!” 这时 远处的天边出现了一 ...

  10. UOJ#46. 【清华集训2014】玄学

    传送门 分析 清华集训真的不是人做的啊嘤嘤嘤 我们可以考虑按操作时间把每个操作存进线段树里 如果现在点x正好使一个整块区间的右端点则更新代表这个区间的点 我们不难发现一个区间会因为不同的操作被分成若干 ...

随机推荐

  1. 爬取百度贴吧前1000页内容(requests库面向对象思想实现)

    此程序以李毅吧为例子,以面向对象的设计思想实现爬取保存网页数据,暂时并未用到并发处理,以后有机会的话会加以改善 首先去百度贴吧分析贴吧地址栏中url后的参数,找到分页对应的参数pn,贴吧名字对应的参数 ...

  2. linux常见的安装软件包命令

    常用的 RPM 软件包命令 安装软件的命令格式 rpm -ivh filename.rpm 升级软件的命令格式 rpm -Uvh filename.rpm 卸载软件的命令格式 rpm -e filen ...

  3. JDK 监控和故障处理工具总结 (转)

    出处:  JDK 监控和故障处理工具总结 JDK 监控和故障处理工具总结 JDK 命令行工具 jps:查看所有 Java 进程 jstat: 监视虚拟机各种运行状态信息 jinfo: 实时地查看和调整 ...

  4. 初试spark java WordCount

    初始环境:OS X 10.10.5 准备:boot2docker 进入boot2docker后安装 docker-spark  地址: https://github.com/sequenceiq/do ...

  5. easyui在table单元格中添加进度条

    function XR_jd(alue, rowData, rowIndex){ var value; ...... var htmlstr = '<div class="easyui ...

  6. JS基础_字面量和变量

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. O016、搭建实验环境

    参考https://www.cnblogs.com/CloudMan6/p/5350536.html   在学习 OpenStack 各服务之前,需要先搭建一个实验环境.   一个看得到摸得着而且能让 ...

  8. C#和Java的最大不同

    本文摘抄自知乎. 作者:匿名用户链接:https://www.zhihu.com/question/20451584/answer/27163009来源:知乎著作权归作者所有.商业转载请联系作者获得授 ...

  9. War of the Corporations CodeForces - 625B (greed)

    A long time ago, in a galaxy far far away two giant IT-corporations Pineapple and Gogol continue the ...

  10. mysql 存储过程(二)

    存储过程(Stored Procedure): 一组可编程的函数,是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行. 优点(为什 ...