bzoj 3821: 玄学
题目大意
有一个长度为 n 数列,有若干个事件,事件分为操作和询问两种,
一次操作是把数列[l...r] 区间中的每个元素x变成 ax + b mod p。
一次询问是询问 执行了 第l 次到第r次操作后第 k 个元素的值。
解题思路
标解是树套树,且平衡树一层需要写可持久化AVL来卡常。
松爷在考场上给出了一种编程复杂度更低的算法。
单独维护a,b两个系数,我们发现在这道题中的操作是支持结合律的,也就是说我们可以把一段操作后产生的效果提前预处理出来。
考虑用线段树维护把每一段区间操作执行后每一个元素的a和b的值。
等等。。每一个元素?那样的话岂不是要存下 线段树节点个数 * 序列中节点个数 个, 即 n^2 个点了吗?
但是这些点中很多个点的a和b值都是相同的, 很显然的一点是对于一个长度为L的区间, a,b值不同的段数是 O(L) 的。
所以说只要依次存下这L段的位置和a,b的值就可以了。 询问的时候需要先二分确定一下 k 这个数处于哪一段中。
具体实现的时候,因为包含r的区间一定只有在 r操作 出现后才会被询问到,所以说每一次插入的时候只要合并掉所有 R == p 的区间就可以了, 而每个区间只会被更新一次(即区间最右端点被插入的时候),所以复杂度得到保证。
加入操作复杂度为 O(logn), 询问操作复杂度 O(log2n) 。
技巧总结
要挖掘操作自身的一些性质, 并且选用合适的数据结构进行维护。 比如说支持合并操作的就可以用线段树啦
代码
写得丑死了QAQ
听了题目描述一个longlong都没有用炸了好久QAQ
作死地用了vector速度慢得飞起QAQ
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#define MAXN 200005
#define MAXT 2500005
#define pb push_back
using namespace std;
int read(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
vector <int> xx[MAXT], aa[MAXT], bb[MAXT];
int Q, tt, n, mod, num[MAXN], lastans, cntj, l, r, a, b, k;
long long A, B;
void jiemi(int &x){x ^= lastans;}
inline void update(int t){
int zuo = t + t, zz = , you = t + t + , yy = ;
int sz = xx[zuo].size()-, sy = xx[you].size()-;
while(){
xx[t].pb(max(xx[zuo][zz], xx[you][yy]));
aa[t].pb((long long)aa[zuo][zz]*aa[you][yy] % mod);
bb[t].pb(((long long)bb[zuo][zz]*aa[you][yy] % mod + bb[you][yy]) % mod);
if(zz == sz && yy == sy) break;
if((zz<sz) && ((yy == sy) || xx[zuo][zz+] < xx[you][yy+])) zz ++;
else if((yy<sy) && ((zz==sz) || xx[you][yy+] < xx[zuo][zz+])) yy ++;
else zz ++, yy ++;
}
}
void insert(int t, int l, int r, int L, int R, int p){
if(l == r){
if(L != ){xx[t].pb(); aa[t].pb(); bb[t].pb();}
xx[t].pb(L); aa[t].pb(a); bb[t].pb(b);
if(R != n){xx[t].pb(R+); aa[t].pb(); bb[t].pb();}
return;
}
int mid = l + r >> ;
if(mid >= p) insert(t + t, l, mid, L, R, p);
else insert(t + t + , mid + , r, L, R, p);
if(p == r) update(t);
}
inline int erfen(int t, int l, int r, int p){
while(l + < r){
int mid = l + r >> ;
if(xx[t][mid] <= p) l = mid;
else r = mid-;
}if(xx[t][r] <= p) return r; return l;
}
inline void ask(int t, int p){
int x = erfen(t, , xx[t].size()-, p);
A = (A*aa[t][x]) % mod; B = (B*aa[t][x]%mod+bb[t][x]) % mod;
}
void query(int t, int l, int r, int L, int R, int p){
if(l >= L && r <= R){ask(t, p); return;}
int mid = l + r >> ;
if(L <= mid)query(t + t, l, mid, L, R, p);
if(R >= mid+)query(t + t + , mid + , r, L, R, p);
}
int main(){
scanf("%d%d%d", &tt, &n, &mod);
for(int i = ; i <= n; i ++) num[i] = read();
scanf("%d", &Q);
for(int qq = ; qq <= Q; qq ++){
int cmd; cmd = read();
if(cmd == ){
l = read(); r = read(); a = read(); b = read();
if(tt % == ) jiemi(l), jiemi(r);
insert(, , Q, l, r, ++ cntj);
}else{
l = read(); r = read(); k = read();
if(tt % == ) jiemi(l), jiemi(r), jiemi(k);
A = ; B = ;
query(, , Q, l, r, k);
lastans = (A*num[k]%mod+B) % mod;
printf("%d\n", lastans);
}
}
// system("pause");
return ;
}
bzoj 3821: 玄学的更多相关文章
- BZOJ 2654 & 玄学二分+MST
题意: 给一张图,边带权且带颜色黑白,求出一棵至少包含k条白边的MST SOL: 正常人都想优先加黑边或者是白边,我也是这么想的...你看先用白边搞一棵k条边的MST...然后维护比较黑边跟白边像堆一 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- 【BZOJ3821/UOJ46】玄学(二进制分组,线段树)
[BZOJ3821/UOJ46]玄学(二进制分组,线段树) 题面 BZOJ UOJ 题解 呜,很好的题目啊QwQ. 离线做法大概可以线段树分治,或者直接点记录左右两次操作时的结果,两个除一下就可以直接 ...
- BZOJ 1758 【WC2010】 重建计划
题目链接:重建计划 这道题现在已经成为一道板子题了…… 这是个非常显然的0-1分数规划,可以二分答案之后树分治判定一下.注意树分治的时候如果使用单调队列,需要把所有儿子预先按最大深度排好序,否则会被扫 ...
- bzoj 前100题计划
bzoj前100题计划 xz布置的巨大的坑.. 有空填题解... 1002 轮状病毒 用python手动matrixtree打表. #include<bits/stdc++.h> #def ...
- bzoj 1854 游戏 二分图匹配 || 并查集
题目链接 Description lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当他使用某种装备时,他只能使用该装备的 ...
- BZOJ - 1003 DP+最短路
这道题被马老板毒瘤了一下,TLE到怀疑人生 //然而BZOJ上妥妥地过了(5500ms+ -> 400ms+) 要么SPFA太玄学要么是初始化block被卡到O(n^4) 不管了,不改了 另外D ...
- [BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash)
[BZOJ 4820] [SDOI2017] 硬币游戏(高斯消元+概率论+字符串hash) 题面 扔很多次硬币后,用H表示正面朝上,用T表示反面朝上,会得到一个硬币序列.比如HTT表示第一次正面朝上, ...
- 三种做法:BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster
目录 题意 思路 AC_Code1 AC_Code2 AC_Code3 参考 @(bzoj 2780: [Spoj]8093 Sevenk Love Oimaster) 题意 链接:here 有\(n ...
随机推荐
- MyBatis的getStatement()方法解析
执行junit测试: 解析: 抛出这个异常的原因可能是因为mapper.xml配置文件中<mapper>的namespace属性配置错误造成的,没有根据命名空间的值(全称类名)找到相应映射 ...
- OC编程之道-接口适配之适配器
已有的类与新的接口之间不兼容的问题相当普遍,人们已为它找到了一个解决方案.这个解决方案就是适配器. 1 何为适配器 what 适配器的主要作用是把被适配者的行为传递给管道另一端的客户端. 将一个类的接 ...
- centos 安装pip,使用pip安装django
python版本要2.7.x以上版本,若未安装python执行以下命令安装: wget https://www.python.org/ftp/python/2.7.8/Python-2.7.8.tgz ...
- JS学习进阶中 come on!
1,定义新的属性来扩展对象 新方法:defineProperty() 实例: var data = {}: Object.defineProperty(data,"type",{ ...
- gulp学习-gulpfile
安装gulp 假设已经安装了node 和npm (淘宝的cnpm很适合国内使用). 1.首页全局安装gulp. 1 npm install --global gulp 2.其次局部安装gulp.(注: ...
- Qt5.5.1编译出来的程序出现libgcc_s_dw2-1.dll的解决方案
问题如图: 输入"myudp2016.exe 1 " 后出现 这是因为没有在系统环境变量path里加上相关路径,我们添加如下路径: 比如说WIN7系统-开始-计算机-右键-属性- ...
- 总结一下项目中遇到的分页问题,使用bootstrap-table来做的后台分页,大家可以借鉴一下 (分页第一篇)
前台进入bootstrap的js和css文件,我就不多少了,另外要引进bootstrap-table的js和css 废话不多说,直接代码. 框架为ssm,代码很清楚 <div class=& ...
- [转]C/C++ 程序员必须收藏的资源大全
from: https://github.com/jobbole/awesome-cpp-cn C++ 资源大全中文版 我想很多程序员应该记得 GitHub 上有一个 Awesome – XXX 系列 ...
- MongoDB高可用集群配置的方案
>>高可用集群的解决方案 高可用性即HA(High Availability)指的是通过尽量缩短因日常维护操作(计划)和突发的系统崩溃(非计划)所导致的停机时间,以提高系统和应用的可用性. ...
- MySQL和Lucene索引对比分析
MySQL和Lucene都可以对数据构建索引并通过索引查询数据,一个是关系型数据库,一个是构建搜索引擎(Solr.ElasticSearch)的核心类库.两者的索引(index)有什么区别呢?以前写过 ...