求逆序对最小值(HDU 1394)
PS:维护区间和,时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define pushup(rt) t[rt] = t[rt<<1] + t[rt<<1|1];
const int maxn = 1e5 + 10;
int n, t[maxn], a[maxn];
void build(int l, int r, int rt) {
t[rt] = 0;
if(l == r) return;
int m = (l+r)>>1;
build(lson);
build(rson);
}
void update(int c, int l, int r, int rt) {
if(l == r) {
t[rt]++;
return ;
}
int m = (l+r)>>1;
if(c<=m) update(c, lson);
else update(c, rson);
pushup(rt);
}
int query(int L, int R, int l, int r, int rt) {
if(L<=l && r<=R) return t[rt];
int m = (l+r)>>1;
int ans = 0;
if(L <= m) ans += query(L, R, lson);
if(R > m) ans += query(L, R, rson);
return ans;
}
int main() {
while(~scanf("%d", &n)) {
build(1, n+1, 1);
int ans = 0;
for(int i=0; i<n; i++) {
scanf("%d", a+i); a[i]++;
ans += query(a[i]+1, n+1, 1, n+1, 1);
update(a[i], 1, n+1, 1);
}
int sum = ans;
for(int i=n-1; i>=0; i--) {
ans= ans - (n-a[i]) + (a[i]-1);
sum = min(sum, ans);
}
printf("%d\n", sum);
}
}
求静态区间第k大 (POJ 2104)
用
v
e
c
t
o
r
vector
vector 来存,二分出第
k
k
k 大的值,在
v
e
c
t
o
r
vector
vector 中二分找不超过
c
c
c 的值
时间复杂度:
O
(
n
l
o
g
3
n
)
O(nlog^3n)
O(nlog3n)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define pushup(rt) t[rt] = t[rt<<1] + t[rt<<1|1];
const int maxn = 1e5 + 10;
int n, m, a[maxn];
vector <int> t[maxn<<2];
void build(int l, int r, int rt) {
t[rt].clear();
if(l == r) {
t[rt].push_back(a[l]);
return ;
}
int m = (l+r)>>1;
build(lson);
build(rson);
//t[rt].resize(t[rt<<1].size()+t[rt<<1|1].size());
t[rt].resize(r-l+1);
//利用STL的merge函数吧两个儿子的数列合并
merge(t[rt<<1].begin(),t[rt<<1].end(),\
t[rt<<1|1].begin(),t[rt<<1|1].end(),t[rt].begin());
}
// 计算 L到 R 之间, 不超过 c的个数
int query(int L, int R, int c, int l, int r, int rt) {
if(r<L || l>R) return 0;
if(L<=l && r<=R)
return upper_bound(t[rt].begin(), t[rt].end(), c)-t[rt].begin();
int m = (l+r)>>1, ans = 0;
ans += query(L, R, c, lson);
ans += query(L, R, c, rson);
return ans;
}
int solve(int L, int R, int k) {
int l = 1, r = n;
while(l <= r) {
int mid = (l+r)>>1;
int qur = query(L, R, a[mid], 1, n, 1);
if(qur >= k) r = mid - 1;
else l = mid + 1;
}
return a[l];
}
int main() {
while(~scanf("%d%d", &n, &m)) {
for(int i=1; i<=n; i++) scanf("%d", a+i);
build(1, n, 1);
sort(a+1, a+n+1);
int l, r, k;
for(int i=0; i<m; i++) {
scanf("%d%d%d", &l, &r, &k);
printf("%d\n", solve(l, r, k));
}
}
}