UVA 12345 Dynamic len(set(a[LR]))

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

分析

借助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+2;


#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 = 17;
const int maxnds = maxd*maxn*maxd;
struct Node
{
    Node *lch,*rch;
    int s;
}meo[maxnds];


int a[maxn];
int *const ps = (int*)(meo+1);
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 == 1) 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 == 1) 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 > 0){
        res.push_back(BIT[x]);
        x &= x-1;
    }
}

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 = 0;
    for(auto &nd: p){
        cnt += nd->lch->s;
    }
    return cnt;
}

inline int cal_sum(Prefix &p)
{
    int cnt = 0;
    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 = 0,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],-1);
    modify_bit(x,prv[x]=y,1);
}


//#define LOCAL
int main()
{
#ifdef LOCAL
    freopen("data.txt","r",stdin);
#endif
    //cout<<maxnds;
    nil->lch = nil->rch = nil;
    root[0] = nil;
    int m;
    scanf("%d%d",&n,&m);

    for(int i = 1; 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 = 1; i <= n; i++){
        root[i] = root[i-1];
        build(prv[i],root[i]);
    }

    fill(BIT+1,BIT+n+1,nil);
    char op[2];
    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+1));
        }
        else {
            x++;
            if(a[x] == y) continue; //...
            auto it = SET.lower_bound(pii(a[x],x+1));
            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 : 0);

            SET.erase(pii(a[x],x));
            SET.insert(pii(a[x] = y,x));
        }
    }
    return 0;
}

 

posted @ 2015-12-06 14:24  陈瑞宇  阅读(464)  评论(0编辑  收藏  举报