LOJ2251 [ZJOI2017] 树状数组【线段树】【树套树】
题目分析:
对于一个$add$操作,它的特点是与树状数组的查询相同,会给$1$到它自己产生影响,而$query$操作则会途径所有包含它的树状数组点。现在$add$操作具有前向性(不会影响之后的点)。所以实际上这是求后缀和。
现在我们知道,对于$query(l,r)$,它等于${Xor}_{i=l-1}^{r-1}A[i]$。与原答案异或,得到$A[l-1] \oplus A[r]$,若它为$1$则假,否则为真。所以我们把它看作平面上的点,对于一个$add(l,r)$操作,会对右端点在其中的产生$\frac{1}{r-l+1}$的改变影响,对两端都在其中的产生$\frac{2}{r-l+1}$的改变影响,对左端点在其中的产生$\frac{1}{r-l+1}$的改变影响。标记合并不难。然后标记永久化一下就行了。
对于$l=1$的单独处理。
代码:
#include<bits/stdc++.h>
using namespace std; const int maxn = ; const int mod = ; int n,m,num=,xL,xR,yL,yR,ans;
struct qy{
int cas,l,r;
}Q[maxn]; struct node{
int ch[],root,data;
}T[maxn*]; int fast_pow(int now,int pw){
int res = ,bit = ,fun = now;
while(bit <= pw){
if(bit & pw) res = (1ll*res*fun)%mod;
fun = (1ll*fun*fun)%mod; bit<<=;
}
return res;
} int merge(int p1,int p2){return ((1ll*p1*(-p2)+1ll*p2*(-p1))%mod+mod)%mod;} void Query(int now,int tl,int tr,int l,int r){
int pls = T[now].root,ll = tl,rr = n;
while(true){
int mid = (ll+rr)/;
ans = merge(ans,(-T[pls].data+mod)%mod);
if(mid >= r){
if(!T[pls].ch[]) break;
else pls = T[pls].ch[];
rr = mid;
}else{
if(!T[pls].ch[]) break;
else pls = T[pls].ch[];
ll = mid+;
}
}
int mid = (tl+tr)/;
if(mid >= l){if(T[now].ch[])Query(T[now].ch[],tl,mid,l,r);}
else{if(T[now].ch[])Query(T[now].ch[],mid+,tr,l,r);}
} void M2(int now,int tl,int tr,int data){
if(tl >= yL && tr <= yR){
T[now].data = merge(T[now].data,data);
return;
}
int mid = (tl+tr)/;
if(!T[now].ch[] && !T[now].ch[]){
T[now].ch[] = ++num; T[now].ch[] = ++num;
T[num-].data = ; T[num].data = ;
}
if(mid >= yL) M2(T[now].ch[],tl,mid,data);
if(mid < yR) M2(T[now].ch[],mid+,tr,data);
} void Modify(int now,int tl,int tr,int data){
if(tl >= xL && tr <= xR){
M2(T[now].root,tl,n,data);
return;
}
int mid = (tl+tr)/;
if(mid >= xL){
if(T[now].ch[]==){
num++;T[now].ch[] = num;
num++;T[num-].root = num;T[num].data = ;
}
Modify(T[now].ch[],tl,mid,data);
}
if(mid < xR){
if(T[now].ch[]==){
num++;T[now].ch[] = num;
num++;T[num-].root = num;T[num].data = ;
}
Modify(T[now].ch[],mid+,tr,data);
}
} void read(){
T[].root = ; T[].data = ;
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++) scanf("%d%d%d",&Q[i].cas,&Q[i].l,&Q[i].r);
} void work(){
int cnt = ;
for(int i=;i<=m;i++){
if(Q[i].cas == ){
cnt^=; xL = ,xR = Q[i].l-,yL = Q[i].l,yR = Q[i].r;
Modify(,,n,fast_pow(Q[i].r-Q[i].l+,mod-));
xL = Q[i].l,xR = Q[i].r,yL = Q[i].l,yR = Q[i].r;
Modify(,,n,*fast_pow(Q[i].r-Q[i].l+,mod-)%mod);
xL = Q[i].l,xR = Q[i].r,yL = Q[i].r+,yR = n;
Modify(,,n,fast_pow(Q[i].r-Q[i].l+,mod-));
}else{
ans = ; Query(,,n,Q[i].l-,Q[i].r);
if((Q[i].l == && (!cnt))||Q[i].l != ) printf("%d\n",ans);
else printf("%d\n",(-ans+mod)%mod);
}
}
} int main(){
read();
work();
return ;
}
LOJ2251 [ZJOI2017] 树状数组【线段树】【树套树】的更多相关文章
- hdu 1166:敌兵布阵(树状数组 / 线段树,入门练习题)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- 洛谷P2414 阿狸的打字机 [NOI2011] AC自动机+树状数组/线段树
正解:AC自动机+树状数组/线段树 解题报告: 传送门! 这道题,首先想到暴力思路还是不难的,首先看到y有那么多个,菜鸡如我还不怎么会可持久化之类的,那就直接排个序什么的然后按顺序做就好,这样听说有7 ...
- 树状数组 && 线段树应用 -- 求逆序数
参考:算法学习(二)——树状数组求逆序数 .线段树或树状数组求逆序数(附例题) 应用树状数组 || 线段树求逆序数是一种很巧妙的技巧,这个技巧的关键在于如何把原来单纯的求区间和操作转换为 求小于等于a ...
- 差分+树状数组 线段树【P2357】 守墓人
题目描述-->p2357 守墓人 敲了一遍线段树,水过. 树状数组分析 主要思路: 差分 简单介绍一下差分(详细概念太麻烦,看下面. 给定一个数组 7 8 6 5 1 8 18 20 35 // ...
- hdu1394(枚举/树状数组/线段树单点更新&区间求和)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给出一个循环数组,求其逆序对最少为多少: 思路:对于逆序对: 交换两个相邻数,逆序数 +1 ...
- 树状数组&线段树
先是树状数组. 令这棵树的结点编号为C1,C2...Cn.令每个结点的值为这棵树的值的总和,那么容易发现: C1 = A1 C2 = A1 + A2 C3 = A3 C4 = A1 + A2 + A3 ...
- 【bzoj4785】[Zjoi2017]树状数组 线段树套线段树
题目描述 漆黑的晚上,九条可怜躺在床上辗转反侧.难以入眠的她想起了若干年前她的一次悲惨的OI 比赛经历.那是一道基础的树状数组题.给出一个长度为 n 的数组 A,初始值都为 0,接下来进行 m 次操作 ...
- 数据结构--树状数组&&线段树--基本操作
随笔目的:方便以后对树状数组(BIT)以及基本线段树的回顾 例题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 例题:hdu 1166 敌兵布阵 T ...
- BZOJ_1901_&_ZJU_2112_Dynamic_Rankings_(主席树+树状数组/线段树+(Treap/Splay))
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1901 给出一个长度为n的数列A,有m次询问,询问分两种:1.修改某一位置的值;2.求区间[l, ...
- BZOJ 3333 排队计划 树状数组+线段树
题目大意:给定一个序列.每次选择一个位置,把这个位置之后全部小于等于这个数的数抽出来,排序,再插回去,求每次操作后的逆序对数 首先我们每一次操作 对于这个位置前面的数 因为排序的数与前面的数位置关系不 ...
随机推荐
- Python全栈开发之路 【第十五篇】:jQuery的介绍和选择器
本节内容 什么是jQuery? write less,do more. jQuery是一个快速,小巧,功能丰富的JavaScript库. 它通过易于使用的API在大量浏览器中运行,使得HTML文档遍历 ...
- T-shirt buying CodeForces - 799B (小根堆+STL)
题目链接 思路: 由于题目说了只有1,2,3,三种色号的衣服,然后开三个对应色号的小根堆, 我是根据pair<int,int> 创建了一个以价格小的优先的优先队列. pair中的另外一个i ...
- Day5 Pyhton基础之编码与解码(四)
1.编码与解码 1.1现在常用的编码类型
- 分布式文件系统FastDFS
fastdfs_百度百科https://baike.baidu.com/item/fastdfs/5609710 用FastDFS一步步搭建文件管理系统 - bojiangzhou - 博客园http ...
- 导出数据之CSV
平常开发中,常见的需求就是导出数据为Excel,CSV格式的表格.所以,在此记录一下导出CSV数据的小方法 $fileName = 'demo.csv'; $data = [ ['id'=>1, ...
- MySQL查询优化注意下面的四个细节
原文:http://bbs.landingbj.com/t-0-244231-1.html 在任何一个数据库中,查询优化都是不可避免的一个话题.对于数据库工程师来说,优化工作是最有挑战性的工作.MyS ...
- connect、resource和dba三种标准角色
授权语句:grant connect,resource,dba to zwserver 经过授权以后,用户拥有connect.resource和dba三个角色的权限: (1)Connect 角色,是授 ...
- [转帖]LCD与LED的区别之背光原理与优缺点对比介绍
LCD与LED的区别之背光原理与优缺点对比介绍 http://m.elecfans.com/article/620376.html 时下液晶面板与液晶电视技术已经达到炉火纯青的境界,并已经成为大屏幕平 ...
- [转帖]前端-chromeF12 谷歌开发者工具详解 Sources篇
前端-chromeF12 谷歌开发者工具详解 Sources篇 原贴地址:https://blog.csdn.net/qq_39892932/article/details/82498748 cons ...
- 头文件带和不带.h的区别
所有C++标准库的头文件都是没有.h结尾的.这么做是为了区分,C标准库的头文件和C++标准库的头文件.比如最具代表性的: #include <string.h> // C 标准库头文件,包 ...