前言

考试的时候居然想错了区间贡献,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. 有关g++的Xlinker选项

    事情的起因是,在使用Eclipse配置opencv的库时,发现使用-Wl 选项需要自己在Linker flags的输入框里指定.并不是像使用-l选项或-I选项那样可以直接添加选项的条目就可以了.但是在 ...

  2. c#之如何计算哈希值字符串

    代码如下: /// <summary> /// 计算哈希值字符串 /// </summary> public static string ComputeHash(byte[] ...

  3. arc 092C 2D Plane 2N Points

    题意: 有n个红色的点和n个蓝色的点,如果红色的点的横坐标和纵坐标分别比蓝色的点的横坐标和纵坐标小,那么这两个点就可以成为一对友好的点. 问最多可以形成多少对友好的点. 思路: 裸的二分图匹配,对于满 ...

  4. 小米note3的开发者选项在哪里?怎么进入开发者模式?如何显示布局边界?

    小米note3的开发者选项在哪里?小米note3怎么进入开发者模式1.找到[设置],打开2.点击[我的设备]3.点击[全部参数]4.连续点击[MIUI版本]5次5.之后就会看见提示 “进入到开发者模式 ...

  5. pytest+request 接口自动化测试

    1.安装python3brew update brew install pyenv 然后在 .bash_profile 文件中添加 eval “$(pyenv init -)” pyenv insta ...

  6. flask框架----flask入门

    一.Flask介绍(轻量级的框架,非常快速的就能把程序搭建起来) Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是 ...

  7. mongoose与express

    一.mongoose的使用1.先创建一个项目目录,初始化:npm init -y2.创建一个server.js文件,在该目录下安装mongoose:cnpm install mongoose3.引入m ...

  8. GoldenGate 12.3微服务架构与传统架构的区别

    随着Oracle GoldenGate 12c(12.3.0.1.0)的发布,引入了可用于复制业务数据的新架构. 多年来,这种架构有着不同的称谓,Oracle终于在最后GA发布的版本中,以“Micro ...

  9. foreach嵌套遍历循环的问题

    在foreach嵌套循环中使用==和equals的问题 JSONArray ja1= new JSONArray(); JSONArray ja2 = new JSONArray(); JSONObj ...

  10. SpringMVC中参数接收

    /** *  * SpringMVC中参数接收 * 1.接收简单类型 int String * 2.可以使用对象pojo接收 * 3.可以使用集合数据接收参数 * 页面: name="ids ...