luogu-1975
題意:給出乙個長度為n的數列以及m個交換兩個數的操作,問每次操作後逆序對數量
時間,下標和數的大小三維偏序,,,把交換操作看成是減去兩個數再加上兩個數,套板子就好了
發現這種計數型別的cdq一般有兩種寫法:
感覺應該都差不多,但有些題目用兩種方式寫也有一些優劣之分,比如這道題,用第二種方式感覺就特別的好寫。。。
#include#include#include#include#include#include#include#include#include#includeusing namespace std;
typedef long long ll;
inline char gc()
inline int read()
while(ch>='0'&&ch<='9') ans=(ans<<1)+(ans<<3)+ch-'0',ch=gc();
return ans*fh;
}const int maxn=3e6+100;
struct nodec[maxn],tmp[maxn];
int n,m,b[maxn],cr[maxn],tre[maxn],cl,tot,qtot,d[maxn];
ll ans[maxn];
mapbh;
bool cmp(node x,node y)
int main();
}sort(b+1,b+n+1);b[0]=-1;
for(int i=1;i<=n;i++)
if(b[i]!=b[i-1]) bh[b[i]]=++tot;
for(int i=1;i<=n;i++)
c[i].b=d[i]=bh[c[i].b];
m=read();
for(int i=1;i<=m;i++);
c[++n]=(node);
c[++n]=(node);
c[++n]=(node);
swap(d[x],d[y]);
}sort(c+1,c+n+1,cmp);
cdq(1,n);
for(int i=1;i<=qtot;i++) ans[i]+=ans[i-1];
for(int i=0;i<=qtot;i++) printf("%lld\n",ans[i]);
return 0;
}
Luogu P1975 國家集訓隊 排隊
luogu 1975 國家集訓隊 排隊 quad 很明顯交換後能增加或減少的逆序對的個數只和這兩個數和這兩個數中間的數有關。quad 於是我們需要乙個資料結構能夠快速求出乙個區間內比乙個特定數值大 小的個數。quad 這個資料結構可以是分塊,這在分塊九講裡面有提到過,這裡就不再闡述具體操作過程了。q...
Luogu1501 國家集訓隊 Tree II
題目描述 一棵n個點的樹,每個點的初始權值為1。對於這棵樹有q個操作,每個操作為以下四種操作之一 u v c 將u到v的路徑上的點的權值都加上自然數c u1 v1 u2 v2 將樹中原有的邊 u1,v1 刪除,加入一條新邊 u2,v2 保證操作完之後仍然是一棵樹 u v c 將u到v的路徑上的點的權...
Luogu 2839 國家集訓隊 middle
感覺這題挺好的。首先對於中位數最大有乙個很經典的處理方法就是二分,每次二分乙個陣列中的下標 mid 然後我們把 mid 代回到原來的陣列中檢查,如果乙個數 a geq mid 那麼就把 s 記為 1 否則把 s 記為 1 然後對 s 跑一遍字首和,觀察是否有乙個區間的和不小於 0 讀清楚題意之後發現...