日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Uva 3767 Dynamic len(set(a[L:R])) 树套树

發布時間:2023/11/27 生活经验 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}
#define maxn 1500005
int tmp=0;
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,0,sizeof(root));sz=0;}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]=1;ls[k]=rs[k]=0;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]>1){w[k]--;s[k]--;return;}if(ls[k]*rs[k]==0)k=ls[k]+rs[k];else if(rnd[ls[k]]<rnd[rs[k]])Rturn(k),Del(k,num);elseLturn(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==0)return;for(;x<=n;x+=lowbit(x))Tr.Insert(Tr.root[x],v);
}
void Bit_change(int x,int v)
{if(x==0)return;for(;x<=n;x+=lowbit(x))Tr.Del(Tr.root[x],v);
}
void Bit_query(int x,int num)
{if(x<=0)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+5){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+5){Bit_change(T,MM);Bit_updata(T,x);a[T]=x;}
}
int main()
{scanf("%d%d",&n,&m);for(int i=0;i<1000005;i++)H[i].insert(0),H[i].insert(n+5);for(int i=1;i<=n;i++){scanf("%d",&b[i]);H[b[i]].insert(i);}for(int i=1;i<=n;i++){a[i]=c[b[i]];c[b[i]]=i;Bit_updata(i,a[i]);}char op[5];int x,y;for(int i=1;i<=m;i++){scanf("%s%d%d",op,&x,&y);x++;if(op[0]=='Q'){int Ans1,Ans2;tmp = 0,Bit_query(y,x-1),Ans1=tmp;tmp = 0,Bit_query(x-1,x-1),Ans2=tmp;printf("%d\n",Ans1-Ans2);}elsechange(x,y);}
}

?

轉載于:https://www.cnblogs.com/qscqesze/p/5007267.html

總結

以上是生活随笔為你收集整理的Uva 3767 Dynamic len(set(a[L:R])) 树套树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。