前言

考试的时候居然想错了区间贡献,mdzz

思路

题目看着很方啊,难道要树套树?

但数据范围提醒我们,是nlogn的复杂度

Sort(S)的定义是不是很鬼畜

但我们不动脑子的打表容易发现

连续区间[1,n]内\(a_i^2-a_{i-1}^2\)为连续的奇数

(其实这里直接用初中的完全平方公式就好)

我们再次打表又发现了

连续的奇数的异或和,很有规律的嘛

可以直接O(1)求出

int xx(int x) {
if(x%4==0) return 0;
if(x%4==2) return 2;
if(x%4==1) return x+x-1;
return x+x+1;
}

根据异或的性质(a^a=0)

我们就能计算出任意连续一段的ans了,\(xx(l-1)\)^\(xx(r)\)

虽说允许重复的集合S

但区间如果重叠,他也只计算一次答案,手玩一下很容易看出

也就是集合S还是不允许重复的(重复的删掉是不影响答案的)

合并直接算就好了

我们现在需要一个只需要支持区间更改贡献的数据结构

lsh+线段树真香

struct node {
int l,r,lazy;
int mi,ma,sum;
int full,k;
} e[maxn<<4];
/*
mi,ma维护区间[l,r]最小值
lazy懒惰标记
ok判断区间[l,r]是否全部被计算答案
k判断[mid,mid+1]之间是否连接
ans就是ans啦
*/

ps:可能我的线段树调试的时候打了太多补丁,肯定有比我写的好得多的代码

但也是不难理解的,重要部分我们加以注释

关于int,是会炸的,反正我的数据灰渣

另外提醒

千万别开小了数组,一组询问是两个数偶,我一直报WA

错误

主席树写多了,左右孩子和l,r老是搞混了,mdzz

代码

#include <bits/stdc++.h>
#define ll long long
#define FOR(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
const int maxn=3e5+7;
const ll inf=0x3f3f3f3f3f3f3f3fLL;
int read() {
int x=0,f=1;char s=getchar();
for(; s>'9'||s<'0'; s=getchar()) if(s=='-') f=-1;
for(; s>='0'&&s<='9'; s=getchar()) x=x*10+s-'0';
return x*f;
}
ll xx(ll x) {
if(x%4==0) return 0;
if(x%4==2) return 2;
if(x%4==1) return x+x-1;
return x+x+1;
}
ll calc(ll l,ll r) {return xx(r)^xx(l-1);}
struct node {
int l,r;
ll mi,ma,sum;
bool full,k,lazy;
} e[maxn<<4];
int lsh[maxn<<1],len;
void pushup(int rt) {
if(e[rt].full) return;
if(e[rt].k) // 区间[mid,mid+1]贡献 需要计算
e[rt].sum=e[rt<<1].sum^e[rt<<1|1].sum^calc(lsh[e[rt<<1].r]+1,lsh[e[rt<<1|1].l]);
else if(e[rt<<1].ma==-inf||e[rt<<1|1].mi==inf) //只有一边有值
e[rt].sum=e[rt<<1].sum^e[rt<<1|1].sum;
else //暴力计算
e[rt].sum=e[rt<<1].sum^e[rt<<1|1].sum^(e[rt<<1|1].mi*e[rt<<1|1].mi-e[rt<<1].ma*e[rt<<1].ma); e[rt].ma=max(e[rt<<1].ma,e[rt<<1|1].ma);
e[rt].mi=min(e[rt<<1].mi,e[rt<<1|1].mi);
}
void tag(int rt) {//区间全部计算ans
e[rt].sum=calc(lsh[e[rt].l]+1,lsh[e[rt].r]);
e[rt].full=1;
e[rt].mi=lsh[e[rt].l];
e[rt].ma=lsh[e[rt].r];
}
void pushdown(int rt) {
if(e[rt].lazy==0) return;
if(e[rt].lazy) {//显然
tag(rt<<1);tag(rt<<1|1);
e[rt<<1].lazy=e[rt<<1|1].lazy=1;
e[rt].lazy=0;
}
}
void build(int l,int r,int rt) {//显然
e[rt].l=l,e[rt].r=r;
e[rt].ma=-inf,e[rt].mi=inf;
if(l==r) return;
int mid=(l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
}
void modify(int L,int R,int rt) {
if(L<=e[rt].l&&e[rt].r<=R) {
tag(rt);
e[rt].lazy=1;
return;
}
if(e[rt].full) return;//如果计算过就不用在计算了
pushdown(rt);
int mid=(e[rt].l+e[rt].r)>>1;
if(L<=mid) modify(L,R,rt<<1);
if(R>mid) modify(L,R,rt<<1|1);
if(L<=mid&&R>mid) e[rt].k=1;//区间两边都经过,中间也一定经过,k=1
pushup(rt);
}
struct edge {int opt,x,y;} Q[maxn];//询问
main() {
//read and lsh
int n=read();
FOR(i,1,n) {
Q[i].opt=read();
if(Q[i].opt==1) lsh[++len]=Q[i].x=read(),lsh[++len]=Q[i].y=read();
}
sort(lsh+1,lsh+1+len);
len=unique(lsh+1,lsh+1+len)-lsh-1;
build(1,len,1);
FOR(i,1,n) {
if(Q[i].opt==2) continue;
Q[i].x=lower_bound(lsh+1,lsh+1+len,Q[i].x)-lsh;
Q[i].y=lower_bound(lsh+1,lsh+1+len,Q[i].y)-lsh;
}
//work
FOR(i,1,n) {
if(Q[i].opt==2)
cout<<e[1].sum<<"\n";
else
modify(Q[i].x,Q[i].y,1);
}
return 0;
}

luogu P5105 不强制在线的动态快速排序的更多相关文章

  1. 洛谷 P5105 不强制在线的动态快速排序

    P5105 不强制在线的动态快速排序 题目背景 曦月最近学会了快速排序,但是她很快地想到了,如果要动态地排序,那要怎么办呢? 题目描述 为了研究这个问题,曦月提出了一个十分简单的问题 曦月希望维护一个 ...

  2. P5105 不强制在线的动态快速排序

    P5105 不强制在线的动态快速排序 $\bigoplus \limits_{i=2}^n (a_i^2-a_{i-1}^2) = \bigoplus \limits_{i=2}^n (a_i-a_{ ...

  3. [洛谷P5105]不强制在线的动态快速排序

    题目大意:有一个可重集$S$,有两个操作: $1\;l\;r:$表示把$S$变为$S\cup[l,r]$ $2:$表示将$S$从小到大排序,记为$a_1,a_2,\dots,a_n$,然后求出$\bi ...

  4. luoguP5105 不强制在线的动态快速排序 [官方?]题解 线段树 / set

    不强制在线的动态快速排序 题解 算法一 按照题意模拟 维护一个数组,每次直接往数组后面依次添加\([l, r]\) 每次查询时,暴力地\(sort\)查询即可 复杂度\(O(10^9 * q)\),期 ...

  5. luoguP5105 不强制在线的动态快速排序

    emm 可重集合没用用.直接变成不可重复集合 有若干个区间 每个区间形如[L,R] [L,R]计算的话,就是若干个连续奇数的和.拆位统计1的个数 平衡树维护 加入一个[L,R],把相交的区间合并.之后 ...

  6. [Luogu5105]不强制在线的动态快速排序

    首先集合去重不影响答案,然后打表易得连续自然数平方差异或前缀和的规律,于是问题就变为在线维护区间求并同时更新答案,set记录所有区间,每次暴力插入删除即可.由于每个区间至多只会插入删除一次,故均摊复杂 ...

  7. [EOJ439] 强制在线

    Description 见EOJ439 Solution 先考虑不强制在线怎么做. 按询问区间右端点排序,从左往右扫,维护所有后缀的答案. 如果扫到 \(a[i]\),那么让统计个数的 \(cnt[a ...

  8. hihocoder #1236 Scores (15北京赛区网络赛J) (五维偏序,强制在线,bitset+分块)

    链接:http://hihocoder.com/problemset/problem/1236 思路; 有n个五维的向量,给出q个询问,每个询问是一个五维向量,问有多少个向量没有一维比这个向量大.并且 ...

  9. [BZOJ 3720][JZYZOJ 2016]gty的妹子树 强制在线 树分块/树套树

    jzyzoj的p2016 先码着,强制在线的树分块或者树套树?关键是我树分块还在入门阶段树套树完全不会啊摔   http://blog.csdn.net/jiangyuze831/article/de ...

随机推荐

  1. 关于oracle中的数字类型

    1.关于number类型. 以下是从其文档中摘录出的一句话: p is the precision, or the total number of significant decimal digits ...

  2. ueditor上传图片配置成功,但是如何删除无用的图片

    我使用ueditor作为富文本编辑器,配置已经好了,上传功能也好了.现在的问题是当使用ueditor上传图片的时候,选择了图片就立刻上传到指定的文件夹里,而后续即使没有保存该篇文章内容,即取消操作,图 ...

  3. linux环境下tab键自动缩进4个空格

    1. 进入 root 模式 su root 2. 编辑 /etc/vimrc 文件 root@localhost /home/xiluhua/tscripts $ vi /etc/vimrc 3. 文 ...

  4. mybatis源码解析7---MappedStatement初始化过程

    上一篇我们了解到了MappedStatement类就是mapper.xml中的一个sql语句,而Configuration初始化的时候会加载所有的mapper接口类,而本篇再分析下是如何将mapper ...

  5. MVC 部署HTTPS网站

    一.项目配置 什么是全站HTTPS 全站HTTPS就是指整个网站的所有页面,所有资源全部使用HTTPS链接.当用户的某个请求是明文的HTTP时,应该通过HTTP状态码301永久重定向到对应的HTTPS ...

  6. 自学Java第一周的总结

    在第一周里我花费了不少时间配置jdk的环境变量,并学习了有关java的基本知识,了解了Java中的变量.数据类型以及运算符.我知道了什么是变量并且如何去定义变量,也学会了如何去使用运算符以及对数据类型 ...

  7. Linux 执行文本保存报错 是使用了记事本等工具打开之后导致的

    dos2unix xx.bat    格式化下就好了 安装: yum install -y dos2unix

  8. SQLServer 比like好用的函数 charindex

    比如查找用户名包含有"c"的所有用户, 可以用 use mydatabase select * from table1 where username like'%c%" ...

  9. The Little Prince-12/15

    The Little Prince-12/15 明天四六级考试了呢!!!喵喵喵,愿大家都能取得好成绩. 星星美丽,因为里面有一朵看不见的花. 沙漠美丽,因为沙漠的某处隐藏着一口井. ————生活美好, ...

  10. 计算概论(A)/基础编程练习2(8题)/7:整数的个数

    #include<stdio.h> int main() { ] = {}; // 输入k个正整数 scanf("%d",&k); // 循环读入和进行算术 w ...