CF 220E Little Elephant and Inversions(主席樹+two points)
轉載請註明出處,謝謝http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
題目:給出個序列,問有多少個二元組(i,j)滿足a1a2...alarar + 1... an 逆序對數不超過K
顯然的一個問題是如果(i,j)滿足,那麼(i,j+r) r>=0肯定滿足
所以列舉左端點,維護右端點,典型的two points。
然後就是更新整個區間的逆序對數了。
刪除一個數,或者新增一個數需要得增加或者減少的逆序對數,最好有當時的序列情況。
典型的就是可持久化線段樹。
排序離散化後,從前往後,以及從後往前分別建立主席樹,就是維護字首和字尾。
然後就是two points過程了。更新的時候注意細節就行了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define lowbit(i) (i&(-i))
#define LL long long
using namespace std;
const int N=100005;
const int M=5000000;
int n,m,a[N];
LL k;
vector<int>v;
struct persistent_tree{
int lson[M],rson[M],c[M],T[M];
int tot,m;
void Init(int t,int _m){
tot=0;m=_m;
T[t]=bulid(1,m);
}
int bulid(int l,int r){
int root=tot++;
c[root]=0;
if(l!=r){
int m=(l+r)>>1;
lson[root]=bulid(l,m);
rson[root]=bulid(m+1,r);
}
return root;
}
int update(int root,int pos,int val){
int newroot=tot++,tmp=newroot;
c[newroot]=c[root]+val;
int l=1,r=m;
while(l<r){
int mid=(l+r)>>1;
if(pos<=mid){
rson[newroot]=rson[root];
lson[newroot]=tot++;
newroot=lson[newroot];
root=lson[root];
r=mid;
}
else{
lson[newroot]=lson[root];
rson[newroot]=tot++;
newroot=rson[newroot];
root=rson[root];
l=mid+1;
}
c[newroot]=c[root]+val;
}
return tmp;
}
int query(int root,int l,int r,int L,int R){
if(R<L) return 0;
if(l==L&&r==R)
return c[root];
int m=(l+r)>>1;
if(R<=m) return query(lson[root],l,m,L,R);
else if(L>m) return query(rson[root],m+1,r,L,R);
else return query(lson[root],l,m,L,m)+query(rson[root],m+1,r,m+1,R);
}
void insert(int now,int old,int pos,int val){
T[now]=update(T[old],pos,val);
}
}pre,suf;
int main(){
cin>>n>>k;
v.push_back(-1);
for(int i=1;i<=n;i++){
cin>>a[i];
v.push_back(a[i]);
}
sort(v.begin(),v.end());
v.resize(unique(v.begin(),v.end())-v.begin());
for(int i=1;i<=n;i++)
a[i]=lower_bound(v.begin(),v.end(),a[i])-v.begin();
m=v.size()-1;
pre.Init(0,m);
suf.Init(m+1,m);
for(int i=1;i<=n;i++)
pre.insert(i,i-1,a[i],1);
for(int i=n;i>=1;i--)
suf.insert(i,i+1,a[i],1);
LL cur=0,ans=0;
for(int i=1;i<=n;i++)
cur+=(LL)pre.query(pre.T[i],1,m,a[i]+1,m);
//cur為初始狀態下的逆序對數
for(int i=1,j=2;i<=n;i++){
while(j<=n&&cur>k){
//將j點刪除,便是找到[1,i]中比j大的,[j+1]中比j小的
cur-=(LL)pre.query(pre.T[i],1,m,a[j]+1,m);
cur-=(LL)suf.query(suf.T[j],1,m,1,a[j]-1);
j++;
}
ans+=n-j+1;
if(j==i+1){
//始終保持j>i,刪除j
cur-=(LL)pre.query(pre.T[i],1,m,a[j]+1,m);
cur-=(LL)suf.query(suf.T[j],1,m,1,a[j]-1);
j++;
}
//恢復i+1
//便是找到[1,i]中比i+1大的,[j,m]中比i+1小的
cur+=(LL)pre.query(pre.T[i],1,m,a[i+1]+1,m);
cur+=(LL)suf.query(suf.T[j],1,m,1,a[i+1]-1);
}
cout<<ans<<endl;
return 0;
}
相關文章
- BZOJ4374 : Little Elephant and Boxes
- 主席樹
- 題解:CF1918B Minimize Inversions
- 主席樹模板
- CF 295E Yaroslav and Points(Splay)ROS
- 動態主席樹模板
- (Codeforces Round #136 (Div. 2))A. Little Elephant and Function(遞迴分析,簡單)Function遞迴
- 題解:CF454B Little Pony and Sort by Shift
- CF1648F Two Avenues 題解
- 【資料結構】淺談主席樹資料結構
- SPOJ TTM To the moon(主席樹+區間操作)
- BZOJ4299: Codechef FRBSUM(主席樹)
- 演算法隨筆——主席樹(可持久化線段樹)演算法持久化
- bzoj3439: Kpm的MC密碼(主席樹+DFS序+字典樹)密碼
- 【主席樹】P3919 【模板】可持久化線段樹 1持久化
- SPOJ DQUERY (離線數狀陣列||線上主席樹)陣列
- 可持久化線段————主席樹(洛谷p3834)持久化
- 2024年3月21日 懸繩法 + 珂朵莉樹(ODT) + 主席樹
- CF 293 E Close Vertices (樹的分治+樹狀陣列)陣列
- bzoj4477: [Jsoi2015]字串樹(主席樹+Hash+Lca)JS字串
- Bzoj 1901 Zju2112 Dynamic Rankings(樹狀陣列+主席樹)陣列
- Dr.Elephant mysql connection errorMySqlError
- CF 773 (Div. 1) D. Two Arrays 雙指標 容斥指標
- Grid Points
- CF 240F TorCoder(線段樹)
- 洛谷 P3919 可持久化線段樹 1 之主席樹模板(初級)持久化
- hdu 2665 可持久化線段樹求區間第K大值(函式式線段樹||主席樹)持久化函式
- Dr.Elephant mysql connection error薦MySqlError
- Important Points for Inheritance in JavaImportJava
- bzoj4448: [Scoi2015]情報傳遞(主席樹+Lca)
- bzoj5178: [Jsoi2011]棒棒糖(主席樹)JS
- The Little JavaScript ClosuresJavaScript
- CF940E Cashback 線段樹優化DP優化
- bzoj3110: [Zjoi2013]K大數查詢(主席樹+樹狀陣列)陣列
- bzoj2809: [Apio2012]dispatching(DFS序+主席樹)API
- Machine Learning - Basic pointsMac
- Objects as Points 論文總結Object
- Restore Points 制定回退方案REST