3600 沒有人的算術

2021-07-26 08:20:46 字數 2756 閱讀 2703

time limit: 20 sec  

memory limit: 128 mb

submit: 616  

solved: 280 [

submit][

status][

discuss]

湖北省隊互測 week1 [

submit][

status][

discuss]

可以發現,每時每刻新增的元素加入之前元素組成的集合中,

新集合內的元素兩兩之間一定可以找出嚴格的大小關係

考慮用某資料結構維護已知集合內的元素,支援o(logn)查詢,插入之類

考慮當前新增第k個元素,前k - 1個元素的大小關係已經能在這個資料結構裡體現了

不妨給每個點乙個實數,這樣之前元素的比較就可以直接通過實數比較進行

實數如何選取?給予每個節點乙個區間[l,r],定義該節點的勢能phi[x] = (l[x] + r[x]) / 2

這樣通過勢能比較就行了,能夠比較,能夠查詢,此題的大部分操作就已經解決

詢問的話,用個線段樹維護維護就完成了

最後,資料結構的選擇,不妨使用替罪羊樹,因為區間的限制,使得節點之間的關係要相對靜態

替罪羊樹的話,就是選取乙個定值alpha,對於某個節點,如果其較大的子樹的大小超過該點size * alpha,

則標記這個點,每次插入操作,將標記最淺的那個子樹暴力重構成一棵完全二叉樹

具體的證明可見clj2023年的**

第一遍寫的時候fa和rt沒有維護好(重構可能改變的東西= =)

人傻不能怪社會系列。。。

#include#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;

const int maxn = 1e5 + 10;

const int maxm = 5e5 + 50;

const int t = 4;

typedef double db;

const db alpha = 0.666;

const db eps = 1e-9;

db lp,rp,siz[maxm],phi[maxm],l[maxm],r[maxm];

int n,m,cnt,rt,tp,p,now,ans,fa[maxm],id[maxn*t]

,pos[maxn*t],ch[maxm][2],s[maxm],lc[maxm],rc[maxm];

int getint()

int getcom()

int cmp(const int &x,const int &y)

void maintain(int o)

void build(int o,int l,int r)

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

build(o<<1,l,mid); build(o<<1|1,mid+1,r);

maintain(o);

}void modify(int o,int l,int r,int k,int id)

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

if (k <= mid) modify(o<<1,l,mid,k,id);

else modify(o<<1|1,mid+1,r,k,id);

maintain(o);

}int get_id(int o,int l,int r,int k)

void get_pos(int o,int l,int r,int ql,int qr)

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

if (ql <= mid) get_pos(o<<1,l,mid,ql,qr);

if (qr > mid) get_pos(o<<1|1,mid+1,r,ql,qr);

}int query(int x,int now)

void insert(int &x,int now,db lp,db rp)

db mid = (lp + rp) / 2.00; int d = cmp(x,now);

if (!d) insert(ch[x][d],now,l[x],mid);

else insert(ch[x][d],now,mid,r[x]);

fa[ch[x][d]] = x; siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1.00;

if (siz[ch[x][d]] >= alpha * siz[x]) p = x,lp = l[x],rp = r[x];

}void dfs(int x)

int build_tree(int l,int r,db lp,db rp)

void rebuild()

int main()

} else

}return 0;

}

3600 沒有人的算術

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

bzoj3600 沒有人的算術

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

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

為什麼我沒有copy題面呢?看到題面你就懂了.hh 題意 定義乙個二元組 二元組的兩個元素可以是二元組 如 x,y 其中x可以是 a,b,c 之類的 定義二元組的比較方式 先比較左邊,左邊相同再比較右邊。遞迴比較可以用隨便哪顆平衡樹維護,70分 考慮對於每個 二元組,對他定義乙個實數的對映來表示它的...