题意:

有n个位置,每个位置上的数字是a[i],现在有强制在线的若干个单点删除操作,每次删除的位置都不同,要求每次删除之后求出最大的连续区间逆序对个数

n<=1e5,1<=a[i]<=n

思路:

对于每次删除操作我们可以考虑被删除的数字的贡献

比如区间[l,r]内删除了x这个位置,被分成了[l,x-1]与[x+1,r]两个区间

未删除之前区间总逆序对数可以分为4个部分:[l,x-1]内部,[x+1,r]内部,跨区间,一端为x

一个优秀的结论是内部区间和跨区间部分可以选择两端区间内较小的一段进行暴力枚举计算(启发式),这样每个位置均摊被用到了logn次

然后用总的逆序对数减去其他3部分就是较大区间内部的逆序对数

逆序对部分等价于求某个区间内在[l,r]之间数字的个数,显然使用主席树进行预处理

现在还要维护区间的插入,删除与最大值,这个如果只使用一个splay似乎很难维护多个关键字

大佬new表示并不需要splay,只需要使用set维护被删除的点,就能很快找出被删除的位置处于哪个区间

然而我并不会set,只能照他打一遍了,真是屈辱

 #include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<int> VI;
#define fi first
#define se second s
#define MP make_pair
#define N 110000
#define MOD 1000000007
#define eps 1e-8
#define pi acos(-1)
#define oo 1e9 struct node
{
int l,r,s;
}t[N*]; struct data
{
ll x;
int l,r;
}; ll Ans[N],f[N],ans;
int a[N],root[N],cnt,n; set<int>st;
typedef set<int>::iterator iter;
struct setcmp
{
bool operator()(const data &x,const data &y)
{
return x.x>y.x||(x.x==y.x&&x.l<y.l)||(x.x==y.x&&x.l==y.l&&x.r<y.r);
}
};
set<data,setcmp>S; ll query(int l,int r,int x,int y,int L,int R)
{
if(l>r||x>y) return ;
if(x<=l&&r<=y) return t[R].s-t[L].s;
int mid=(l+r)>>;
ll ans=;
if(x<=mid) ans+=query(l,mid,x,y,t[L].l,t[R].l);
if(y>mid) ans+=query(mid+,r,x,y,t[L].r,t[R].r);
return ans;
} void update(int l,int r,int x,int &p)
{
t[++cnt]=t[p];
p=cnt;
t[p].s++;
if(l==r) return;
int mid=(l+r)>>;
if(x<=mid) update(l,mid,x,t[p].l);
else update(mid+,r,x,t[p].r);
} int read()
{
int v=,f=;
char c=getchar();
while(c<||<c) {if(c=='-') f=-; c=getchar();}
while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
return v*f;
} int main()
{
freopen("zoj4053.in","r",stdin);
freopen("zoj4053.out","w",stdout);
int cas;
scanf("%d",&cas);
while(cas--)
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
cnt=;
ans=;
st.clear();
st.insert();
st.insert(n+);
S.clear();
for(int i=;i<=n;i++)
{
root[i]=root[i-];
update(,n,a[i],root[i]);
}
ll ans=;
for(int i=;i<=n;i++) ans+=query(,n,a[i]+,n,root[],root[i-]);
S.insert((data){ans,,n});
f[]=ans;
for(int i=;i<=n;i++)
{
ans=(*S.begin()).x;
Ans[i]=ans;
ll x;
scanf("%lld",&x);
x^=ans;
iter p=st.lower_bound(x);
int r=*p;
p--;
int l=*p;
l++; r--;
S.erase(S.lower_bound((data){f[l],l,r}));
ans=f[l];
ll t1=;
ll t2=;
if(x-l<r-x)
{
for(int i=l;i<x;i++)
{
t1+=query(,n,,a[i]-,root[i],root[x-]);
ans-=query(,n,,a[i]-,root[i],root[r]);
}
ans-=query(,n,,a[x]-,root[x],root[r]);
t2=ans;
}
else
{
for(int i=x+;i<=r;i++)
{
t2+=query(,n,a[i]+,n,root[x],root[i-]);
ans-=query(,n,a[i]+,n,root[l-],root[i-]);
}
ans-=query(,n,a[x]+,n,root[l-],root[x-]);
t1=ans;
}
if(<=x-)
{
S.insert((data){t1,l,x-});
f[l]=t1;
}
if(x+<=r)
{
S.insert((data){t2,x+,r});
f[x+]=t2;
}
st.insert(x);
}
for(int i=;i<n;i++) printf("%lld ",Ans[i]);
printf("%lld\n",Ans[n]); }
return ;
}

【ZOJ4053】Couleur(主席树,set,启发式)的更多相关文章

  1. 【BZOJ3123】森林(主席树,启发式合并)

    题意:一个带点权的森林,要求维护以下操作: 1.询问路径上的点权K大值 2.两点之间连边 n,m<=80000 思路:如果树的结构不发生变化只需要维护DFS序 现在因为树的结构发生变化,要将两棵 ...

  2. [bzoj3123][Sdoi2013]森林_主席树_启发式合并

    森林 bzoj-3123 Sdoi-2013 题目大意:给定一片共n个点的森林,T个操作,支持:连接两个不在一棵树上的两个点:查询一棵树上路径k小值. 注释:$1\le n,T \le 8\cdot ...

  3. 洛谷 P4755 - Beautiful Pair(主席树+分治+启发式优化)

    题面传送门 wssb,我紫菜 看到这类与最大值统计有关的问题可以很自然地想到分治,考虑对 \([l,r]\) 进行分治,求出对于所有 \(l\le x\le y\le r\) 的点对 \((x,y)\ ...

  4. BZOJ3123[Sdoi2013]森林——主席树+LCA+启发式合并

    题目描述 输入 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负 ...

  5. luoguP3302 [SDOI2013]森林 主席树 启发式合并

    题目链接 luoguP3302 [SDOI2013]森林 题解 本来这题树上主席树暴力启发式合并就完了 结果把lca写错了... 以后再也不这么写了 复杂度\(O(nlog^2n)\) "f ...

  6. 洛谷P4197 Peaks&&克鲁斯卡尔重构树学习笔记(克鲁斯卡尔重构树+主席树)

    传送门 据说离线做法是主席树上树+启发式合并(然而我并不会) 据说bzoj上有强制在线版本只能用克鲁斯卡尔重构树,那就好好讲一下好了 这里先感谢LadyLex大佬的博客->这里 克鲁斯卡尔重构树 ...

  7. 白白的(baibaide)——树状数组套主席树+splay

    题目 [题目描述] 有一个长度为 $n$ 的序列 $a_1, a_2, \dots, a_n$,一开始每个位置都是白色.如果一个区间中每个位置都是白色,则称这是一个白白的区间.如果一个白白的区间向左或 ...

  8. bzoj 3123 [Sdoi2013]森林(主席树,lca,启发式合并)

    Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...

  9. BZOJ 3123: [Sdoi2013]森林 [主席树启发式合并]

    3123: [Sdoi2013]森林 题意:一个森林,加边,询问路径上k小值.保证任意时刻是森林 LCT没法搞,树上kth肯定要用树上主席树 加边?启发式合并就好了,小的树dfs重建一下 注意 测试点 ...

随机推荐

  1. Android(java)学习笔记148:网易新闻RSS客户端应用编写逻辑过程

    1.我们的项目需求是编写一个新闻RSS浏览器,RSS(Really Simple Syndication)是一种描述和同步网站内容的格式,是使用最广泛的XML应用.RSS目前广泛用于网上新闻频道,bl ...

  2. 机器学习(1)- 概述&线性回归&逻辑回归&正则化

    根据Andrew Ng在斯坦福的<机器学习>视频做笔记,已经通过李航<统计学习方法>获得的知识不赘述,仅列出提纲. 1 初识机器学习 1.1 监督学习(x,y) 分类(输出y是 ...

  3. Vue的elementUI实现自定义主题

    使用vue开发项目,用到elementUI,根据官网的写法,我们可以自定义主题来适应我们的项目要求,下面来介绍一下两种方法实现的具体步骤,(可以参考官方文档自定义主题官方文档),先说项目中没有使用sc ...

  4. db2的离线备份和还原

    db2cmd中运行命令 1.做一个离线备份(db2cmd)mstsc—>db2cmd db2 connect to  mydb                    #连接数据库 db2 lis ...

  5. javaEE(9)_在线支付

    一.目前主要的两种支付方案 二.支付流程 1.用户在提交订单完成选择易宝支付按钮后,会跳转到如下页面选择要支付的银行,如下所示: <!DOCTYPE HTML PUBLIC "-//W ...

  6. UIScrollView和MultiThreading、UITextField、Keyboard

  7. 洛谷 P2872 道路建设

    https://www.luogu.org/problemnew/show/P2872 算是比较裸的并查集了,已经有路的两个点之间建一条代价为0的边,路径长度计算两点之间的距离,做并查集就好咯. #i ...

  8. (26)zabbix脚本报警介质自定义(钉钉)

    zabbix机器人告警配置 首先在钉钉中创建一个群然后设置群机器人添加自定义机器人(webhook...) 添加后复制其中的webhook地址到报警脚本dingding.py中的webhook=... ...

  9. Re:从零开始的Linux之路(文件权限)

    基于 Red Hat Enterprise Linux 7.5 或者 CentOS 7.4 基本概念 Linux最核心的一个概念就是:Linux里面任何东西都可以被视为一个文件,包括系统本身(说到底L ...

  10. (转))iOS App上架AppStore 会遇到的坑

    iOS App上架AppStore 会遇到的坑   前言:非原创 文章摘自:http://zhuanlan.zhihu.com/100000PM/20010725 相信大家一定非常「深恶痛疾」AppS ...