Uva 3767 Dynamic len(set(a[L:R])) 树套树
Dynamic len(set(a[L:R]))
Time Limit: 20 Sec
Memory Limit: 256 MB
题目连接
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3767
Description
给你n个数,m次操作
Q x y 询问[x+1,y]有多少个不同的数
M x y 将第x+1个数修改成y
Input
n,50000 询问50000次,修改的y的数最大1e6
Output
Sample Input
7 4
1 2 1 3 2 1 4
Q 1 6
M 3 2
Q 1 6
Q 3 5
Sample Output
3
2
1
HINT
题意
题解:
树套树
首先我们对于每个元素,将这个数的值修改成 这个数前面离最近的数,在哪儿
比如样例 1 2 1 3 2 1 4
我们可以看出 0 0 1 0 2 3 0
然后我们每次的询问操作就是查询区间有多少个数小于l,这个就是平衡树或者主席树来解决就好了(划分树已经成为了时代的眼泪
修改的话,就得树套树,然后我们再用set维护一下这个数后面的数是什么,前面的数是什么就好了
注意,修改会修改3个数哦~
代码:
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<cstring>
#include<set>
#include<ctime>
using namespace std;
inline long long read()
{
long long x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
#define maxn 1500005
int tmp=;
int a[maxn];
int c[maxn];
int b[maxn];
int n,m;
set<int> H[maxn];
////////////////treap
struct Treap
{
int root[maxn],sz,s[maxn],ls[maxn],rs[maxn],v[maxn],w[maxn],rnd[maxn];
void init()
{
memset(root,,sizeof(root));
sz=;
}
void Updata(int k)
{
s[k]=s[ls[k]]+s[rs[k]]+w[k];
}
void Rturn(int &k)
{
int t;
t=ls[k],ls[k]=rs[t],rs[t]=k,s[t]=s[k];
Updata(k);k=t;
}
void Lturn(int &k)
{
int t;
t=rs[k],rs[k]=ls[t],ls[t]=k,s[t]=s[k];
Updata(k);k=t;
}
void Insert(int &k,int num)
{
if(!k)
{
k=++sz;s[k]=w[k]=;ls[k]=rs[k]=;rnd[k]=rand();
v[k]=num;return;
}
s[k]++;
if(v[k]==num)w[k]++;
else if(num<v[k])
{
Insert(ls[k],num);
if(rnd[ls[k]]<rnd[k])
Rturn(k);
}
else
{
Insert(rs[k],num);
if(rnd[rs[k]]<rnd[k])
Lturn(k);
}
}
void Del(int &k,int num)
{
if(v[k]==num)
{
if(w[k]>){
w[k]--;
s[k]--;
return;
}
if(ls[k]*rs[k]==)
k=ls[k]+rs[k];
else if(rnd[ls[k]]<rnd[rs[k]])
Rturn(k),Del(k,num);
else
Lturn(k),Del(k,num);
}
else if(num<v[k]){
Del(ls[k],num);
s[k]--;
}
else{
Del(rs[k],num);
s[k]--;
}
}
void Find(int k,int num)
{
if(!k)return;
if(v[k]<=num){
tmp+=s[ls[k]]+w[k];
Find(rs[k],num);
}
else Find(ls[k],num);
}
}Tr; ///////////////////// /////////////////////线段树
int lowbit(int x)
{
return x&(-x);
}
void Bit_updata(int x,int v)
{
if(x==)return;
for(;x<=n;x+=lowbit(x))
Tr.Insert(Tr.root[x],v);
}
void Bit_change(int x,int v)
{
if(x==)return;
for(;x<=n;x+=lowbit(x))
Tr.Del(Tr.root[x],v);
}
void Bit_query(int x,int num)
{
if(x<=)return;
for(;x;x-=lowbit(x))
Tr.Find(Tr.root[x],num);
}
/////////////////////////// void change(int x,int y)
{
Bit_change(x,a[x]);
H[b[x]].erase(x);
int T = *H[b[x]].upper_bound(x);
if(T!=n+)
{
Bit_change(T,x);
Bit_updata(T,a[x]);
a[T]=a[x];
}
b[x]=y;
T = *--H[b[x]].upper_bound(x);
a[x]=T;int MM = T;
Bit_updata(x,a[x]);
H[y].insert(x);
T = *H[b[x]].upper_bound(x);
if(T!=n+)
{
Bit_change(T,MM);
Bit_updata(T,x);
a[T]=x;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<;i++)
H[i].insert(),H[i].insert(n+);
for(int i=;i<=n;i++)
{
scanf("%d",&b[i]);
H[b[i]].insert(i);
}
for(int i=;i<=n;i++)
{
a[i]=c[b[i]];
c[b[i]]=i;
Bit_updata(i,a[i]);
}
char op[];int x,y;
for(int i=;i<=m;i++)
{
scanf("%s%d%d",op,&x,&y);x++;
if(op[]=='Q')
{
int Ans1,Ans2;
tmp = ,Bit_query(y,x-),Ans1=tmp;
tmp = ,Bit_query(x-,x-),Ans2=tmp;
printf("%d\n",Ans1-Ans2);
}
else
change(x,y);
}
}
Uva 3767 Dynamic len(set(a[L:R])) 树套树的更多相关文章
- (待修莫队 没过! 抽空在检查)Dynamic len(set(a[L:R])) UVA - 12345
#include <iostream> #include <cstdio> #include <sstream> #include <cstring> ...
- Dynamic len(set(a[L:R])) UVA - 12345(这么过分一定要写博客)
给出一个有n个元素的数组,有以下两种操作:Q x y,求出区间[x,y)内不同元素的个数, M x y,把第x个元素的值修改为y.注意题目中的下标是从0开始的 这题超级超级坑 妈的一个水题找了几个小时 ...
- 【题解】Luogu UVA12345 Dynamic len(set(a[L:R]))
原题传送门 这题要用动态莫队,我博客里有介绍 这道题和luogu P1903 [国家集训队]数颜色 / 维护队列差不多,解法就在上面那篇博客里qaq 主要的问题是如何排序? 排序有三个关键字: 1.左 ...
- 【BZOJ1901】 Zju2112 Dynamic Rankings(树套树)
[题意] 给定一个含有n个数的序列a[1],a[2],a[3]--a[n], 程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[j]中第k小的数是多少(1≤k ...
- bzoj 1901: Zju2112 Dynamic Rankings(树套树)
1901: Zju2112 Dynamic Rankings 经典的带改动求区间第k小值问题 树套树模板,我是用的线段树套splay实现的,并且用的数组模拟的,所以可能空间略大,bzoj过了,zoj过 ...
- zoj2112 Dynamic Rankings (主席树 || 树套树)
The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...
- 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树套树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1901 这题调了我相当长的时间,1wa1a,我是第一次写树套树,这个是树状数组套splay,在每个区间 ...
- [luogu2617][bzoj1901][Zju2112]Dynamic Rankings【树套树+树状数组+主席树】
题目网址 [传送门] 题目大意 请你设计一个数据结构,支持单点修改,区间查询排名k. 感想(以下省略脏话inf个字) 真的强力吹爆洛谷数据,一般的树套树还给我T了一般的点,加强的待修主席树还给我卡了几 ...
- 【bzoj1901】dynamic ranking(带修改主席树/树套树)
题面地址(权限题) 不用权限题的地址 首先说说怎么搞带修改主席树? 回忆一般的kth问题,我们的主席树求的是前缀和,这样我们在目标区间的左右端点的主席树差分下就能求出kth. 那么我们如何支持修改操作 ...
随机推荐
- MyBatis 入门到精通(三) 高级结果映射
MyBatis的创建基于这样一个思想:数据库并不是您想怎样就怎样的.虽然我们希望所有的数据库遵守第三范式或BCNF(修正的第三范式),但它们不是.如果有一个数据库能够完美映射到所有应用程序,也将是非常 ...
- 通过ListActivity使用ListView布局方法
先简单的介绍一下ListActivity ListActivity是一个专门显示ListView的Activity类,它内置了ListView对象,只要我们设置了数据源,就会自动地显示出来.ListA ...
- Android常用控件之FragmentTabHost的使用
最近在学TabHost时发现TabActivity在API level 13以后不用了,所以就去寻找它的替换类,找到FragmentActivity,可以把每个Fragment作为子tab添加到Fra ...
- awk简单使用『摘.非原创』
1 awk简介 awk是一种编程语言,用于在linux/unix下对文本和数据进行处理.数据可以来自标准输入.一个或多个文件,或其它命令的输出.它支持用户自定义函数和动态正则表达式等先进功能,是lin ...
- codeforces 678E Another Sith Tournament 概率dp
奉上官方题解 然后直接写的记忆化搜索 #include <cstdio> #include <iostream> #include <ctime> #include ...
- windows各种程序中文显示乱码又找不到原因时
我电脑上的各种程序,如xshell,Navicat for MySQL都不正常显示中文,该软件的编码,utf-8,gbk,gb2312来回切换好几回,没一次正常,最好解决办法如下 进入控制 ...
- 《Python 学习手册4th》 第十章 Python语句简介
''' 时间: 9月5日 - 9月30日 要求: 1. 书本内容总结归纳,整理在博客园笔记上传 2. 完成所有课后习题 注:“#” 后加的是备注内容 (每天看42页内容,可以保证月底看完此书) “重点 ...
- <转>Python 参数知识(变量前加星号的意义)
csdn上的牛人就是多,加油 —————————————————————————— 过量的参数 在运行时知道一个函数有什么参数,通常是不可能的.另一个情况是一个函数能操作很多对象.更有甚者,调用自身的 ...
- linux下配置双网卡及RAC规划——1
使用背景: 操作系统:centos 虚拟机:virtualbox RAC系统中需要双网卡,一个为公共的网络环境,一个为私有的网络环境,从而需要搭建双网络. 在菜单FILE中选择preferences, ...
- C#相关图书推荐
C#入门经典(第6版) 作 者 [美] Karli Watson,Jacob Vibe Hammer,Jon D Reid 等 著: 出 版 社 清华大学出版社 出版时间 2014-01-0 ...