题意:询问区间唯一元素个数,单点修改。

分析

借助Unique snowflakes, Can you answer these queries II的思想,唯一性可以借助元素上一次出现的位置来判断。

对于询问(x,y),只要回答[x,y)区间内,上一次出现位置prv[i] < x的元素数量即可。

对于修改来说,如果原来的a[x]的后继元素存在,则要修改后继的前驱。

a[x]修改成y以后,找到x位置前的y出现位置,作为x位置的前驱,并修改x位置以后下一个y的前驱。

寻找前驱后继可以用一个set保存(value,pos)的二元组,平方分解可以更暴力地找。

目前已知实现方法有三种,1.线段树套平衡树,2.平方分解,3.BIT套函数式线段树。

线段树套一个平衡树,想要偷懒试了试pb_ds里面的rb_tree,但是join的时候值域不能相交,并且只能nlognlogn建树。O((n+m)lognlogn)

改成套SBT,可以做到nlogn建线段树,然后写挂了。(实际上是我不知道SBT删除的时候怎么maintain。也许改成Treap或者BST会过。)。O(nlogn + mlognlogn)

平方分解,比较容易写,10s时限很稳。O(nlogn + m(N/BlogB+BlogB)) = O(nlogn + N^(3/2)log(N^(1/2)))

BIT套函数式,好写,内存消耗大(UVA的内存没有限制吗?)。O(nlogn,mlognlogn)

(实在过不了的话,因为暴力修改是O(1),可以水过...

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp> using namespace std;
using namespace __gnu_pbds; typedef pair<int,int> pii; typedef long long ll; const int maxn = 5e4+; #define value first
#define index second
tree <pii,null_type> SET; #define para Node *(&o), int l = 0, int r = n
#define lo (o->lch)
#define ro (o->rch)
#define Tvar int md = (l+r)>>1;
#define lsn lo,l,md
#define rsn ro,md,r
#define insd x<=l&&r<=y const int maxd = ;
const int maxnds = maxd*maxn*maxd;
struct Node
{
Node *lch,*rch;
int s;
}meo[maxnds]; int a[maxn];
int *const ps = (int*)(meo+);
int prv[maxn];
int n; Node *root[maxn]; Node *const nil = meo;
Node *freeNode = nil; void build(int v,para)
{
*(++freeNode) = *o;
o = freeNode;
o->s++;
if(r-l == ) return;
Tvar
if(v < md) build(v,lsn);
else build(v,rsn);
} void inst(int v,int d,para)
{
if(o == nil){
*(++freeNode) = *o;
o = freeNode;
}
o->s += d;
if(r-l == ) return;
Tvar
if(v < md) inst(v,d,lsn);
else inst(v,d,rsn);
} Node *BIT[maxn]; typedef vector<Node*> Prefix; Prefix X,Y; void q_pfx_bit(int x, Prefix &res)
{
res.clear();
while(x > ){
res.push_back(BIT[x]);
x &= x-;
}
} void modify_bit(int x,int v,int d)
{
while(x <= n){
inst(v,d,BIT[x]);
x += x&-x;
}
} inline int cal_lft(Prefix &p)
{
int cnt = ;
for(auto &nd: p){
cnt += nd->lch->s;
}
return cnt;
} inline int cal_sum(Prefix &p)
{
int cnt = ;
for(auto &nd: p){
cnt += nd->s;
}
return cnt;
} #define dump(P,ch)\
for(auto &nd: P){\
nd = nd->ch;\
} int query(int v, int l = ,int r = n)
{
if(r<=v) return cal_sum(Y)-cal_sum(X);
Tvar
if(v <= md) {
dump(X,lch) dump(Y,lch)
return query(v,l,md);
}
int tmp = cal_lft(Y)-cal_lft(X);
dump(X,rch) dump(Y,rch)
return tmp + query(v,md,r);
} inline void modify(int x,int y)
{
modify_bit(x,prv[x],-);
modify_bit(x,prv[x]=y,);
} //#define LOCAL
int main()
{
#ifdef LOCAL
freopen("data.txt","r",stdin);
#endif
//cout<<maxnds;
nil->lch = nil->rch = nil;
root[] = nil;
int m;
scanf("%d%d",&n,&m); for(int i = ; i <= n; i++) {
scanf("%d",a+i);
prv[i] = ps[a[i]];
ps[a[i]] = i;
SET.insert(pii(a[i],i));
} for(int i = ; i <= n; i++){
root[i] = root[i-];
build(prv[i],root[i]);
} fill(BIT+,BIT+n+,nil);
char op[];
int x,y;
while(m--){
scanf("%s%d%d",op,&x,&y); //0 based
if(*op == 'Q'){
q_pfx_bit(x,X);
q_pfx_bit(y,Y);
X.push_back(root[x]);
Y.push_back(root[y]);
printf("%d\n",query(x+));
}
else {
x++;
if(a[x] == y) continue; //...
auto it = SET.lower_bound(pii(a[x],x+));
if(it != SET.end() && it->value == a[x]){
modify(it->index,prv[x]);
} it = SET.lower_bound(pii(y,x));//找后继,需要保证(y,x)不存在 if(it != SET.end() && it->value == y){
modify(it->index,x);
} modify(x,(it != SET.begin() && (--it)->value == y)? it->index : ); SET.erase(pii(a[x],x));
SET.insert(pii(a[x] = y,x));
}
}
return ;
}

UVA 12345 Dynamic len(set(a[LR]))的更多相关文章

  1. UVA 12345 Dynamic len(带修莫队)

    Dynamic len [题目链接]Dynamic len [题目类型]带修莫队 &题解: 莫队可以单点更改,只要再多加一维,代表查询次数,排序的时候3个关键字. 之后循环离线的时候,先暴力时 ...

  2. 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/in ...

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

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

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

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

  5. UVA 11990 ``Dynamic'' Inversion 动态逆序对

    ``Dynamic'' Inversion Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 https://uva.onlinejudge.org/index ...

  6. UVA 11990 `Dynamic'' Inversion CDQ分治, 归并排序, 树状数组, 尺取法, 三偏序统计 难度: 2

    题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

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

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

  8. UVA 11990 ”Dynamic“ Inversion(线段树+树状数组)

    [题目链接] UVA11990 [题目大意] 给出一个数列,每次删去一个数,求一个数删去之前整个数列的逆序对数. [题解] 一开始可以用树状数组统计出现的逆序对数量 对于每个删去的数,我们可以用线段树 ...

  9. UVA 11990 ``Dynamic'' Inversion (序列分治)

    26天以前做过的一道题,之前的做法是分治预处理,树套树在线修改,复杂度为O(nlogn+m*logn*logn),代码量较大. 本来想学习一下cdq分治的,看到论文上的凸包.斜率就暂时放一边了,只知道 ...

随机推荐

  1. centos 7 安装 最小化 碰到的问题

    1)分区推荐 2)更新yum源  (收藏 https://mirror.webtatic.com/yum/el7/) cd /etc/yum.repos.d/ 更新源 wget http://mirr ...

  2. jenkins出现的问题

    1.增加服务器时 要修改时,,需要设置 2:出现这个问题是 执行了npm install node-sass

  3. hive取等分数据

    %sql select t3.* from ( select t2.* ,row_number() over(partition by t2.pt order by t2.pv) as rn2 fro ...

  4. my24_mysql索引-使用篇

    索引提示 SELECT * FROM table1 USE INDEX (col1_index,col2_index) ; SELECT * FROM table1 IGNORE INDEX (col ...

  5. ace+validate表单验证(两种方法)

    //修改密码(直接在validate中验证提交) $("#changePassword").on(ace.click_event, function() { var html = ...

  6. 前台js escape及后台C# Server.UrlEncode 对QueryString传参的含~!@#$%^&*等特殊字符的处理

    通常情况下,我们在List列表页面,会包含Create,Edit,Delete等操作按钮, 而通常的处理是: Create按钮跳转到DataCreate.aspx Edit按钮跳转到DataEdit. ...

  7. IntelliJ IDEA里找不到javax.servlet的jar包

    此处有小坑,请注意: https://mvnrepository.com网站查询到的servlet的包的格式为: provided group: 'javax.servlet', name: 'jav ...

  8. LeetCode 887.鸡蛋掉落(C++)

    每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去. 你知道存在楼层 F ,满足 0 <= F <= N 任何从高于 F 的楼层落下的鸡蛋都会碎,从 F 楼层或比它低的楼层落下的 ...

  9. 用信鸽来解释 HTTPS

    原文:http://blog.jobbole.com/113883/ ----------------------------------------------------------------- ...

  10. rake 任务参数传递问题解决

    原文 :  https://robots.thoughtbot.com/how-to-use-arguments-in-a-rake-task namespace :tweets do desc 'S ...