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])) 树套树的更多相关文章

  1. (待修莫队 没过! 抽空在检查)Dynamic len(set(a[L:R])) UVA - 12345

    #include <iostream> #include <cstdio> #include <sstream> #include <cstring> ...

  2. Dynamic len(set(a[L:R])) UVA - 12345(这么过分一定要写博客)

    给出一个有n个元素的数组,有以下两种操作:Q x y,求出区间[x,y)内不同元素的个数, M x y,把第x个元素的值修改为y.注意题目中的下标是从0开始的 这题超级超级坑 妈的一个水题找了几个小时 ...

  3. 【题解】Luogu UVA12345 Dynamic len(set(a[L:R]))

    原题传送门 这题要用动态莫队,我博客里有介绍 这道题和luogu P1903 [国家集训队]数颜色 / 维护队列差不多,解法就在上面那篇博客里qaq 主要的问题是如何排序? 排序有三个关键字: 1.左 ...

  4. 【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 ...

  5. bzoj 1901: Zju2112 Dynamic Rankings(树套树)

    1901: Zju2112 Dynamic Rankings 经典的带改动求区间第k小值问题 树套树模板,我是用的线段树套splay实现的,并且用的数组模拟的,所以可能空间略大,bzoj过了,zoj过 ...

  6. zoj2112 Dynamic Rankings (主席树 || 树套树)

    The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...

  7. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树套树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 这题调了我相当长的时间,1wa1a,我是第一次写树套树,这个是树状数组套splay,在每个区间 ...

  8. [luogu2617][bzoj1901][Zju2112]Dynamic Rankings【树套树+树状数组+主席树】

    题目网址 [传送门] 题目大意 请你设计一个数据结构,支持单点修改,区间查询排名k. 感想(以下省略脏话inf个字) 真的强力吹爆洛谷数据,一般的树套树还给我T了一般的点,加强的待修主席树还给我卡了几 ...

  9. 【bzoj1901】dynamic ranking(带修改主席树/树套树)

    题面地址(权限题) 不用权限题的地址 首先说说怎么搞带修改主席树? 回忆一般的kth问题,我们的主席树求的是前缀和,这样我们在目标区间的左右端点的主席树差分下就能求出kth. 那么我们如何支持修改操作 ...

随机推荐

  1. ActionBarSherlock的学习笔记(三) ------------ ActionBarSherlock中的overflow及item的点击事件

    定义一个自定义的ActionBar的title,并添加一个overflow的Action   Item. 代码实现 如下  : import android.os.Bundle; import and ...

  2. POJ 1042 Gone Fishing

    题意:一个人要在n个湖中钓鱼,湖之间的路径是单向的,只能走1->2->3->...->n这一条线路,告诉你每个湖中一开始能钓到鱼的初始值,和每钓5分钟就减少的数量,以及湖之间的 ...

  3. matlab 学习

    http://blog.sina.com.cn/s/blog_7086379501012pc5.html <a href = "http://blog.sina.com.cn/s/bl ...

  4. poj-3056 http://poj.org/problem?id=3056

    http://poj.org/problem?id=3056 The Bavarian Beer Party Time Limit: 6000MS   Memory Limit: 65536K Tot ...

  5. 【LR】版本问题

    前台信息工作笔记本系统是: widows7 64位操作系统 (1)loadrunner11 软件 --兼容性问题的解决与环境配置要求 地址:http://bgwan.blog.163.com/blog ...

  6. iOS数据存储之对象归档

    iOS数据存储之对象归档 对象归档 对象归档是iOS中数据持久化的一种方式. 归档是指另一种形式的序列化,但它是任何对象都可以实现的更常规的类型.使用对模型对象进行归档的技术可以轻松将复杂的对象写入文 ...

  7. QT-【转】基础(略)

    第0篇 开始学习Qt 与Qt Creator 第1篇 基础(一)Qt开发环境的搭建和hello world 第2篇 基础(二)编写Qt多窗口程序 第3篇 基础(三)Qt登录对话框 第4篇 基础(四)添 ...

  8. JS单例设计模式

     单例,指的是只有一个实例的对象.    在应用单例模式时,生成单例的类必须保证只有一个实例的存在,很多时候整个系统只需要拥有一个全局对象,才有利于协调系统整体的行为.比如在整个系统的配置文件中,配置 ...

  9. [转]JQuery.Ajax之错误调试帮助信息

    下面是Jquery中AJAX参数详细列表: 参数名 类型 描述 url String (默认: 当前页地址) 发送请求的地址. type String (默认: "GET") 请求 ...

  10. [算法] 选择排序 Selection sort

    选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理如下.首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然 ...