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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

BZOJ 1901 Dynamic Rankings(线段树+treap)

發(fā)布時(shí)間:2025/7/14 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ 1901 Dynamic Rankings(线段树+treap) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目鏈接:http://61.187.179.132/JudgeOnline/problem.php?id=1901

題意:給出一個(gè)數(shù)列,兩種操作:(1)詢問區(qū)間第K小值;(2)修改某個(gè)位置的值。

思路:首先,將數(shù)列建成線段樹。線段樹的每個(gè)節(jié)點(diǎn)建立一棵treap,以方便統(tǒng)計(jì)。插入時(shí),從上到下,刪除原位置上的數(shù)字的值,插入新的值;詢問時(shí),二分答案x,在區(qū)間查找小于等于x的個(gè)數(shù)與K比較。

?




struct Node
{
? ? int val,size,pri;
? ? int L,R;
};




Node a[N*100];
int e;


struct node
{
? ? int L,R,root;
};


node A[N<<2];


int d[N];


int newNode(int val)
{
? ? int x=++e;
? ? a[x].val=val;
? ? a[x].size=1;
? ? a[x].L=a[x].R=-1;
? ? a[x].pri=rand();
? ? return x;
}


void pushUp(int k)
{
? ? if(k==-1) return;
? ? a[k].size=1;
? ? if(a[k].L!=-1) a[k].size+=a[a[k].L].size;
? ? if(a[k].R!=-1) a[k].size+=a[a[k].R].size;
}


void rotL(int &x)
{
? ? int y=a[x].R;
? ? a[x].R=a[y].L;
? ? a[y].L=x;
? ??
? ? pushUp(x);
? ? pushUp(y);
? ? x=y;
}


void rotR(int &x)
{
? ? int y=a[x].L;
? ? a[x].L=a[y].R;
? ? a[y].R=x;
? ??
? ? pushUp(x);
? ? pushUp(y);
? ? x=y;
}






void insert(int &k,int val)
{
? ? if(k==-1)
? ? {
? ? ? ? k=newNode(val);
? ? }
? ? else if(val<a[k].val)
? ? {
? ? ? ? insert(a[k].L,val);
? ? ? ? if(a[a[k].L].pri>a[k].pri) rotR(k);
? ? }
? ? else
? ? {
? ? ? ? insert(a[k].R,val);
? ? ? ? if(a[a[k].R].pri>a[k].pri) rotL(k);
? ? }
? ? pushUp(k);
}




void del(int val,int &k)
{
? ? if(k==-1) return;
? ? else if(val<a[k].val)?
? ? {
? ? ? ? del(val,a[k].L);
? ? }
? ? else if(val>a[k].val)?
? ? {
? ? ? ? del(val,a[k].R);
? ? }
? ? else
? ? {
? ? ? ? if(a[k].L==-1&&a[k].R==-1) k=-1;
? ? ? ? else if(a[k].L==-1)?
? ? ? ? {
? ? ? ? ? ? k=a[k].R;
? ? ? ? }
? ? ? ? else if(a[k].R==-1)?
? ? ? ? {
? ? ? ? ? ? k=a[k].L;
? ? ? ? }
? ? ? ? else?
? ? ? ? {
? ? ? ? ? ? if(a[a[k].L].pri<a[a[k].R].pri)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? rotL(k);
? ? ? ? ? ? ? ? del(val,a[k].L);
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? rotR(k);
? ? ? ? ? ? ? ? del(val,a[k].R);
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? pushUp(k);
}


int cal(int k,int root)
{
? ? int ans=0,p=root;
? ? while(p!=-1)
? ? {
? ? ? ? if(k<a[p].val) p=a[p].L;
? ? ? ? else?
? ? ? ? {
? ? ? ? ? ? ans++;
? ? ? ? ? ? if(a[p].L!=-1) ans+=a[a[p].L].size;
? ? ? ? ? ? p=a[p].R;
? ? ? ? }
? ? }
? ? return ans;
}


void build(int t,int L,int R)
{
? ? A[t].L=L;
? ? A[t].R=R;
? ??
? ? A[t].root=newNode(d[L]);
? ? int i;
? ? for(i=L+1;i<=R;i++)?
? ? {
? ? ? ? insert(A[t].root,d[i]);
? ? }
? ??
? ? if(L==R) return;
? ? int mid=(L+R)>>1;
? ? build(t*2,L,mid);
? ? build(t*2+1,mid+1,R);
}


int DFS(int t,int L,int R,int k)
{
? ? if(L>A[t].R||R<A[t].L) return 0;
? ? if(L<=A[t].L&&A[t].R<=R)
? ? {
? ? ? ? return cal(k,A[t].root);
? ? }
? ? return DFS(t*2,L,R,k)+DFS(t*2+1,L,R,k);
}


int query(int L,int R,int k)
{
? ? int low=-5,high=INF,mid,ans;
? ? while(low<=high)
? ? {
? ? ? ? mid=(low+high)>>1;
? ? ? ? if(DFS(1,L,R,mid)>=k) ans=mid,high=mid-1;
? ? ? ? else low=mid+1;
? ? }
? ? return ans;
}


int n,m;


void update(int t,int pos,int k)
{
? ? if(pos<A[t].L||pos>A[t].R) return;
? ? del(d[pos],A[t].root);
? ? insert(A[t].root,k);
? ? update(t*2,pos,k);
? ? update(t*2+1,pos,k);
}


int main()
{
? ? RD(n,m);
? ? int i;
? ? FOR1(i,n) RD(d[i]);
? ? build(1,1,n);
? ? int L,R,k;
? ? char op[5];
? ? while(m--)
? ? {
? ? ? ? RD(op);
? ? ? ? if(op[0]=='Q')
? ? ? ? {
? ? ? ? ? ? RD(L,R,k);
? ? ? ? ? ? if(L>R) swap(L,R);
? ? ? ? ? ? PR(query(L,R,k));
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? RD(L,R);
? ? ? ? ? ? update(1,L,R);
? ? ? ? ? ? d[L]=R;
? ? ? ? }
? ? }
}





總結(jié)

以上是生活随笔為你收集整理的BZOJ 1901 Dynamic Rankings(线段树+treap)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。