只區間出現一次的數就是上一次出現在位置在區間外的數,這個可以用主席樹實現,然後套用超級鋼琴的思想就可以了。
#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...