树状数组求逆序对
模板
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long ll;const int MAXN = 100000;ll n, cnt, a[MAXN + 1], b[MAXN + 1];//b:树状数组,ls:离散后数组ll k;struct mark{ ll n, ln;//数值,原先编号; } ls[MAXN + 1];ll lowbit(ll x){return x & (- x);}void add(ll x, ll y)//x处加上y{ for(; x <= n; x += lowbit(x)) { b[x] += y; }}ll sum(ll x){ ll ans = 0; for(; x; x -= lowbit(x)) ans += b[x]; return ans;}int cmp(const mark & a, const mark & b){return a.n < b.n;}int main(){ int i, j; ios::sync_with_stdio(false); while(cin >> n >> k) { memset(a, 0, sizeof(a)); memset(b, 0, sizeof(b)); memset(ls, 0, sizeof(ls)); for(i = 1; i <= n; i ++) cin >> a[i], ls[i].n = a[i], ls[i].ln = i; sort(ls + 1, ls + n + 1, cmp); cnt = 1; a[ls[1].ln] = cnt; for(i = 2; i <= n; i ++) { if((ls[i - 1].n != ls[i].n)) cnt ++; a[ls[i].ln] = cnt; } ll ans = 0; for(i = n; i >= 1; i--) { ans += sum(a[i] - 1); add(a[i], 1); } if(ans - k < 0) cout << 0 << endl; else cout << ans - k << endl; } return 0;}
题目:
HDU 4911
HDU 3743
HDU 1394
HDU 5497
NOIP 2012