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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[BZOJ3600]没有人的算术

發布時間:2025/7/25 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [BZOJ3600]没有人的算术 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

咕了這么久終于把這題補回來了...

關鍵在于怎么維護“數”的大小,直接用平衡樹即可,每個平衡樹節點維護的是一個實數區間$[l,r]$,那么$mid$就是這個節點所代表的“數”的大小,也即權值

如果我們使用的平衡樹在插入后需要調整樹的形態,那么被調整的部分的權值都需要被重新計算,如果平衡樹深度太大,那么精度會爆,所以要用重量平衡樹(修改影響到的子樹大小和平衡樹深度都不會太大)

這里用替罪羊樹,原生支持重新計算權值,過幾天補個旋轉treap咕咕咕

btw...替罪羊樹是不用記父親的...是我智障了

#include<stdio.h> typedef double du; const du al=.75; int max(int a,int b){return a>b?a:b;} du rk[500010]; struct num{int l,r;num(int a=0,int b=0){l=a;r=b;} }v[500010]; bool operator>(num a,num b){return rk[a.l]==rk[b.l]?rk[a.r]>rk[b.r]:rk[a.l]>rk[b.l];} bool operator==(num a,num b){return rk[a.l]==rk[b.l]&&rk[a.r]==rk[b.r];} int l[500010],r[500010],siz[500010],M,sc,rt,fs; du sl,sr; int insert(int&x,du lv,du rv,num d){du mv=(lv+rv)*.5;int t;if(x==0){x=++M;siz[x]=1;v[x]=d;rk[x]=mv;return x;}if(v[x]==d)return x;t=v[x]>d?insert(l[x],lv,mv,d):insert(r[x],mv,rv,d);siz[x]=siz[l[x]]+siz[r[x]]+1;if(sc&&(l[x]==sc||r[x]==sc))fs=x;if(siz[x]*al<max(siz[l[x]],siz[r[x]])){sc=x;sl=lv;sr=rv;}return t; } int tmp[500010],C; void dfs(int x){if(l[x])dfs(l[x]);tmp[++C]=x;if(r[x])dfs(r[x]); } int build(int L,int R,du lv,du rv){int mid=(L+R)>>1,x=tmp[mid];du mv=(lv+rv)*.5;rk[x]=mv;l[x]=L<mid?build(L,mid-1,lv,mv):0;r[x]=mid<R?build(mid+1,R,mv,rv):0;siz[x]=siz[l[x]]+siz[r[x]]+1;return x; } int insert(num d){sc=fs=0;int p=insert(rt,0,1,d);if(sc){C=0;dfs(sc);(sc!=rt?(l[fs]==sc?l:r)[fs]:rt)=build(1,C,sl,sr);}return p; } int mx[400010],pos[100010]; void modify(int p,int l,int r,int x){if(l==r){mx[x]=l;return;}int mid=(l+r)>>1;if(p<=mid)modify(p,l,mid,x<<1);elsemodify(p,mid+1,r,x<<1|1);l=mx[x<<1];r=mx[x<<1|1];mx[x]=rk[pos[l]]>=rk[pos[r]]?l:r; } int query(int L,int R,int l,int r,int x){if(L<=l&&r<=R)return mx[x];int mid=(l+r)>>1,res=0,t;if(L<=mid){t=query(L,R,l,mid,x<<1);if(rk[pos[t]]>rk[pos[res]])res=t;}if(mid<R){t=query(L,R,mid+1,r,x<<1|1);if(rk[pos[t]]>rk[pos[res]])res=t;}return res; } int main(){int n,m,i,l,r,k;char s[5];scanf("%d%d",&n,&m);rk[0]=-1;insert(num());for(i=1;i<=n;i++)pos[i]=1;for(i=1;i<=n;i++)modify(i,1,n,1);while(m--){scanf("%s%d%d",s,&l,&r);if(s[0]=='C'){scanf("%d",&k);pos[k]=insert(num(pos[l],pos[r]));modify(k,1,n,1);}elseprintf("%d\n",query(l,r,1,n,1));} }

轉載于:https://www.cnblogs.com/jefflyy/p/9286077.html

總結

以上是生活随笔為你收集整理的[BZOJ3600]没有人的算术的全部內容,希望文章能夠幫你解決所遇到的問題。

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