BZOJ 3262(Treap+树状数组)
题面
分析
分三维考虑
对第一维,直接排序
对第二维和第三维,我们这样考虑
朴素的方法是建k棵Treap,第i棵Treap里存第二维值为k的第三维数值
每次查询一组(a,b,c),只要在1~b的Treap里查询<=c的数的个数即可
这样可以保证一定是合法的,因为排序,第一维肯定<=a,因为Treap根据值域建,第二维肯定<=b
又根据平衡树的性质,第三维肯定<=c
这样总的时间复杂度是\(O(nk\log n)\),无法接受
我们考虑用树状数组的拆分方法,把一组询问拆成\(\log k\)组询问
第i棵Treap存储的是第二维在${[i- \rm lowbit}(i)+1,i] $之间的三元组的第三维
然后按照树状数组查找和更新的方法求出答案即可
时间复杂度\(O(n \log n \log k)\)
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<stack>
#define maxn 100005
#define maxv 200005
#define maxs 5000005
#define lson tree[p].l
#define rson tree[p].r
using namespace std;
int n,k;
struct node {
int l;
int r;
int val;
int dat;
int cnt;
int size;
} tree[maxs];
int tot=0;
int root[maxv];
void update(int p) {
tree[p].size=tree[lson].size+tree[rson].size+tree[p].cnt;
}
void zig(int &p) {
int q=tree[p].l;
tree[p].l=tree[q].r;
tree[q].r=p;
p=q;
update(tree[p].r);
update(p);
}
void zag(int &p) {
int q=tree[p].r;
tree[p].r=tree[q].l;
tree[q].l=p;
p=q;
update(tree[p].l);
update(p);
}
int New(int val) {
tree[++tot].val=val;
tree[tot].dat=rand();
tree[tot].cnt=1;
tree[tot].size=1;
return tot;
}
void insert(int &p,int val) {
if(p==0) {
p=New(val);
return;
}
if(val==tree[p].val) {
tree[p].cnt++;
update(p);
return;
}
if(val<tree[p].val) {
insert(lson,val);
if(tree[lson].dat>tree[p].dat) zig(p);
} else {
insert(rson,val);
if(tree[rson].dat>tree[p].dat) zag(p);
}
update(p);
}
int get_rank_by_val(int p,int val) {
if(p==0) return 0;
if(val==tree[p].val) {
return tree[lson].size+tree[p].cnt;
}
if(val<tree[p].val) {
return get_rank_by_val(lson,val);
}
return get_rank_by_val(rson,val)+tree[lson].size+tree[p].cnt;
}
inline int lowbit(int x) {
return x&-x;
}
void update(int x,int v){
while(x<=k){ //注意,树状数组是根据值域建的,所以范围是k,不要写成x<=n
// printf(" tree %d, update %d\n",x,v);
insert(root[x],v);
x+=lowbit(x);
}
}
int query(int x,int v){
int level=0;
while(x){
// printf(" tree %d, query %d\n",x,v );
level+=get_rank_by_val(root[x],v);
x-=lowbit(x);
}
return level;
}
struct flower{
int s;
int c;
int m;
friend bool operator == (flower a,flower b){
return a.s==b.s&&a.c==b.c&&a.m==b.m;
}
friend bool operator < (flower a,flower b){
if(a.s==b.s){
if(a.c==b.c) return a.m<b.m;
else return a.c<b.c;
}else{
return a.s<b.s;
}
}
}a[maxn];
int level[maxn];
int cnt[maxn];
stack<int>s;
int main() {
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d %d %d",&a[i].s,&a[i].c,&a[i].m);
}
sort(a+1,a+1+n);
for(int i=1;i<=n;i++){
if(a[i]==a[i+1]) s.push(i);
else{
level[i]=query(a[i].c,a[i].m);
while(!s.empty()){
level[s.top()]=level[i];
s.pop();
}
}
update(a[i].c,a[i].m);
}
for(int i=1;i<=n;i++){
cnt[level[i]]++;
}
for(int i=0;i<=n-1;i++){
printf("%d\n",cnt[i]);
}
}
BZOJ 3262(Treap+树状数组)的更多相关文章
- BZOJ - 3224 Tyvj 1728 普通平衡树 (treap/树状数组)
题目链接 treap及树状数组模板题. treap版: #include<bits/stdc++.h> using namespace std; typedef long long ll; ...
- [bzoj3196][Tyvj1730]二逼平衡树_树套树_位置线段树套非旋转Treap/树状数组套主席树/权值线段树套位置线段树
二逼平衡树 bzoj-3196 Tyvj-1730 题目大意:请写出一个维护序列的数据结构支持:查询给定权值排名:查询区间k小值:单点修改:查询区间内定值前驱:查询区间内定值后继. 注释:$1\le ...
- BZOJ 2141 排队(树状数组套主席树)
解法很多的题,可以块套树状数组,可以线段树套平衡树.我用的是树状数组套主席树. 题意:给出一段数列,m次操作,每次操作是交换两个位置的数,求每次操作后的逆序对数.(n,m<=2e4). 对于没有 ...
- bzoj 1878 SDOI2009树状数组 离线操作
本来想写2120的,结果想起来了这个 我们先对于询问左端点排序,用树状数组存区间字母个数,对于每种字母, 第一次出现的位置记录为1,剩下的记录为0,然后记录下,每种颜色 后面第一个和他相同颜色的位置 ...
- bzoj 4785: [Zjoi2017]树状数组【树套树】
参考:https://www.cnblogs.com/ljh2000-jump/p/6686960.html 由于操作反过来了,所以显然树状数组维护后缀和,所以本来想查询(1,r)-(1,l-1),现 ...
- BZOJ 4765(分块+树状数组)
题面 传送门 "奋战三星期,造台计算机".小G响应号召,花了三小时造了台普通计算姬.普通计算姬比普通计算机要厉害一些 .普通计算机能计算数列区间和,而普通计算姬能计算树中子树和.更 ...
- BZOJ 4785 [Zjoi2017]树状数组 | 二维线段树
题目链接 BZOJ 4785 题解 这道题真是令人头秃 = = 可以看出题面中的九条可怜把求前缀和写成了求后缀和,然后他求的区间和却仍然是sum[r] ^ sum[l - 1],实际上求的是闭区间[l ...
- BZOJ 4999 LCA树状数组差分维护DFS序
Description 给一颗树,每个节点有个初始值 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x 2. Q i j x(0<=x<2 ...
- bzoj 3262 陌上花开 - CDQ分治 - 树状数组
Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当 ...
随机推荐
- 基于socket实现大文件上传
import socket 1.客户端: 操作流程: 先拿到文件--->获取文件大小---->创建字典 1.制作表头 header 如何得到 他是一个二进制字符串 序列化得到 字典字符串 ...
- 洛谷 P2783 有机化学之神偶尔会做作弊(Tarjan,LCA)
题目背景 LS中学化学竞赛组教练是一个酷爱炉石的人. 有一天他一边搓炉石一边监考,而你作为一个信息竞赛的大神也来凑热闹. 然而你的化竞基友却向你求助了. “第1354题怎么做”<--手语 他问道 ...
- uboot学习之五-----uboot如何启动Linux内核
uboot和内核到底是什么?uboot实质就是一个复杂的裸机程序:uboot可以被配置也可以做移植: 操作系统内核本身就是一个裸机程序,和我们学的uboot和其他裸机程序没有本质的区别:区别就是我们操 ...
- 2018-09-20-weekly
Algorithm 最长有效括号 What 给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度. How 这里可以用栈来求解,需要定义个start变量来记录合法括号串的起 ...
- j函数 判断以 什么开头
1.str.charAt(index) 返回字符串中指定位置的字符. str 是字符串 我们要将获得的数据 转化为字符串 var code = res.statusCode.toString(); ...
- 【串线篇】spring boot自动配置原理
配置文件到底能写什么?怎么写?自动配置原理: 配置文件能配置的属性参照 一.自动配置原理: 1.1.SpringBoot启动的时候加载主配置类,开启了自动配置功能 @EnableAutoConfigur ...
- python数据分析第二版:pandas
一:pandas 两种数据结构:series和dataframe series:索引(索引自动生成)和标签(人为定义)组成---返回一个对象 obj = pd.Series([1,2,3,4]) ob ...
- selenium 自动化的坑(2)
UI自动化,一天一坑系列(2) 今天要介绍的坑是这样的:在使用google浏览器的过程中,F12查看页面元素,我的操作步骤是先F12,然后点击箭头,接着点击要查找的元素来实现元素查看,不知道你是不是这 ...
- Queue2链队列
链队列 1 #include <iostream> using namespace std; template <class T> class Queue { private: ...
- 让VirtualBox虚拟机实现开机自动后台运行
转至:http://www.cnblogs.com/top5/archive/2012/01/19/2326234.html 测试环境:Host OS: Windows 7 x64 Guest OS: ...