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. 那么我们如何支持修改操作 ...
随机推荐
-
升级到iOS9之后的相关适配
iOS9AdaptationTips(iOS9开发学习交流群:458884057) iOS9适配系列教程[中文在页面下方]转自@iOS程序犭袁 (截至2015年9月26日共有10篇,后续还将持续更新. ...
-
[转] FastMM使用详解
FastMM使用详解 一.引言 FastMM 是适用于delphi的第三方内存管理器,在国外已经是大名鼎鼎,在国内也有许多人在使用或者希望使用,就连 Borland 也在delphi2007 ...
-
解决阿里云SLB无法添加https证书的问题
私钥是在Linux中通过下面的openssl命令生成的: openssl req -new -newkey rsa:2048 -nodes -keyout cnblogs.key -out cnblo ...
-
UVA 10892 - LCM Cardinality
Problem F LCM Cardinality Input: Standard Input Output: Standard Output Time Limit: 2 Seconds A pair ...
-
php处理中文字符串
使用mbstring 先转换成UTF-8编码 mb_convert_encoding(Input::get('tags'),'UTF-8') mbstring用法参考http://php.net/ma ...
-
略谈cpu架构种类
一直对x86/i386/i686/x86_64这些东西感觉很不清楚,查些资料,解决部分问题,小记一番. Question1:什么是x86? x86或80x86是英特尔Intel首先开发制造的一种微处理 ...
-
AttributeError: &#39;int&#39; object has no attribute &#39;log&#39;
我们有时候在对组数进行操作时候,偶尔会出现这个问题. 比如: #coding:utf- import pandas as pd import numpy as np if __name__ == '_ ...
-
uri.js的用法事例
来源于:http://smoothprogramming.com/tutorials/get-set-query-string-values-from-url-using-uri-js/ Get or ...
-
Docker 简单运用
Docker 帮助系统管理员和程序员在容器中开发应用程序,并且可以扩展到成千上万的节点,容器和 VM(虚拟机)的主要区别是,容器提供了基于进程的隔离,而虚拟机提供了资源的完全隔离.虚拟机可能需要一分钟 ...
-
2维FFT算法实现——基于GPU的基2快速二维傅里叶变换
上篇讲述了一维FFT的GPU实现(FFT算法实现——基于GPU的基2快速傅里叶变换),后来我又由于需要做了一下二维FFT,大概思路如下. 首先看的肯定是公式: 如上面公式所描述的,2维FFT只需要拆分 ...