bzoj 3600 沒有人的算術 替罪羊樹

2021-07-25 19:21:33 字數 1796 閱讀 4753

為什麼我沒有copy題面呢?看到題面你就懂了....hh

題意:定義乙個二元組(二元組的兩個元素可以是二元組)

如(x,y),其中x可以是(a,(b,c))之類的

定義二元組的比較方式:先比較左邊,左邊相同再比較右邊。

遞迴比較可以用隨便哪顆平衡樹維護,70分

考慮對於每個 二元組,對他定義乙個實數的對映來表示它的大小,想象我們在將它插入平衡樹時,一路比較,按照比較結果判斷是插入左子樹還是右子樹,那實際上它最終的位置就是他的對映,70分做法即為如此,缺陷在於比較是log的,可是,我們既然已經知道他所在最終位置(對映出的實數),且對映的大小關係等價於它本身的大小關係,那為何不用對映出的實數去構造新的二元組呢?這樣比較就變成o(1)的了。

可是,對映顯然只是一種相對的位置關係,常用的平衡樹均有旋轉操作,那就意味著對映大小改變,將不斷的重新計算對映,得不償失。可是,非旋轉treap和替罪羊樹並無旋轉操作啊!

**:

#include#include#include#include#include#include#include#include#include#include#include#define n 500020

using namespace std;

inline int read()

while(ch>='0'&&ch<='9')

return x*f;

}int n,m;

double a[n];

int ts[n],tot;

int r,rt,pos[n],mx[n];

struct data

double mv=(lv+rv)/2.0;

int mid=(l+r)>>1;

u=ts[mid];a[u]=mv;

build(ls[u],l,mid-1,lv,mv);

build(rs[u],mid+1,r,mv,rv);

size[u]=size[ls[u]]+size[rs[u]]+1;

}void rebuild(int &u,double lv,double rv)

int insert(int &u,double lv,double rv,data val)

int p;

if(val==v[u])return u;

else

}else r=u;

return p;

}}sc;

void add(int u,int l,int r,int v)

int mid=(l+r)>>1;

if(v<=mid)add(u<<1,l,mid,v);

else add(u<<1|1,mid+1,r,v);

int x=mx[u<<1],y=mx[u<<1|1];

if(a[pos[x]]>1;int ret=0;

if(y<=mid)return query(u<<1,l,mid,x,y);

else if(x>mid)return query(u<<1|1,mid+1,r,x,y);

else

return ret;

}int main()

); for(int i=1;i<=n;i++)pos[i]=1;

for(int i=1;i<=n;i++)add(1,1,n,i);

for(int i=1;i<=m;i++)

);if(r)sc.rebuild(rt,0,1);r=0;

add(1,1,n,k);

} else printf("%d\n",query(1,1,n,l,r));

}}

bzoj3600 沒有人的算術

time limit 20 sec memory limit 128 mb submit 1118 solved 452 submit status discuss 湖北省隊互測 week1 submit status discuss 神。神題。具體過程太抽象了。我們考慮如果能有一種方法能快速得到排...

3600 沒有人的算術

time limit 20 sec memory limit 128 mb submit 616 solved 280 submit status discuss 湖北省隊互測 week1 submit status discuss 可以發現,每時每刻新增的元素加入之前元素組成的集合中,新集合內的元...

3600 沒有人的算術

vfk太強了。題目大意 維護一段由集合組成的序列,集合分左右,支援合併操作,求區間內字典序最大的的位置。還有wjmzbmr的 重量平衡樹和字尾平衡樹在資訊學奧賽中的應用 好像是2013年的 思路大致是用平衡樹維護這些集合的相對大小,然後給它乙個實數值表示大小。用平衡樹查詢可以做到logn。最後再用線...