BZOJ4504 主席樹 K個串

2021-08-03 09:31:21 字數 1228 閱讀 8904

只區間出現一次的數就是上一次出現在位置在區間外的數,這個可以用主席樹實現,然後套用超級鋼琴的思想就可以了。

#include 

#include

#include

#include

#include

using

namespace

std;

const

int n=100010;

typedef

long

long ll;

typedef pairint> parli;

int n,k,cnt,a[n],lst[n],rt[n];

int ls[n*50],rs[n*50];

ll add[n*50];

parli mx[n*50];

struct stp

int mid=l+r>>1;

if(r<=mid) add(ls[lg],ls[g],l,r,x,l,mid);

else

if(l>mid) add(rs[lg],rs[g],l,r,x,mid+1,r);

else add(ls[lg],ls[g],l,mid,x,l,mid),add(rs[lg],rs[g],mid+1,r,x,mid+1,r);

mx[g]=max(mx[ls[g]],mx[rs[g]]); mx[g].first+=add[g];

}parli query(int g,int l,int r,int l,int r)

void build(int &g,int l,int r)

int mid=l+r>>1;

build(ls[g],l,mid); build(rs[g],mid+1,r);

mx[g]=max(mx[ls[g]],mx[rs[g]]);

}int main()

build(rt[0],1,n);

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

} for(int i=1;iif(cur.l==cur.r) continue;

parli q;

if(cur.l1,1,n);

q.push((stp));

}if(cur.p1,cur.r,1,n);

q.push((stp));

}} printf("%lld\n",q.top().val);

return

0;}

bzoj4504 K個串 優先佇列 主席樹

首先如果沒有出現次數的限制的話,這題就是超級鋼琴 但由於有了這個限制,不能簡單地用字首和 考慮順著做的時候每個點的貢獻,如果a i x,x上次出現位置是lst x 可以用乙個map來記 那它會給右端點為 i,n 左端點為 lst x 1,i 的區間帶來x的貢獻 根據szr巨佬的說法,主席樹的本質就是...

區間第k大(主席樹)

學了一下主席樹模板題,當初看了網上的主席樹講解都沒有看懂,後面看了嗶哩嗶哩的uestc的主席樹,終於看懂了思想。每次更新的複雜度都為logn。每次更新的話就是對要更新的點路徑上的點重新更加乙個,然後進行對沒有影響的那些進行連邊。然後用乙個root記錄每乙個線段樹的根節點下標。include incl...

主席樹(區間第k小)

k th number 求區間內第k小的數。主席樹的板子題 主席樹左子樹存小值,右邊大值,用sum記錄一下子樹節點個數。對 l,r 的查詢區間,root r root l 1 可得出 l,r 的差值,也就是大小的個數 include include include include include i...