4163 hzwer与逆序对 (codevs + 权值线段树 + 求逆序对)

题目链接:http://codevs.cn/problem/4163/

题目:

 

思路:

  线段树求逆序对板题,不过一开始因为离散化姿势不对一直T,后面换了离散化方法,刚好卡过。

代码实现如下:

  1 #include <set>
  2 #include <map>
  3 #include <queue>
  4 #include <stack>
  5 #include <cmath>
  6 #include <ctime>
  7 #include <bitset>
  8 #include <cstdio>
  9 #include <string>
 10 #include <vector>
 11 #include <cstdlib>
 12 #include <cstring>
 13 #include <iostream>
 14 #include <algorithm>
 15 using namespace std;
 16 
 17 typedef long long LL;
 18 typedef pair<LL, LL> pLL;
 19 typedef pair<LL, int> pli;
 20 typedef pair<int, LL> pil;;
 21 typedef pair<int, int> pii;
 22 typedef unsigned long long uLL;
 23 
 24 #define lson rt<<1
 25 #define rson rt<<1|1
 26 #define lowbit(x) x&(-x)
 27 #define name2str(name) (#name)
 28 #define bug printf("*********\n");
 29 #define debug(x) cout<<#x"=["<<x<<"]" <<endl;
 30 #define IO ios::sync_with_stdio(false),cin.tie(0);
 31 
 32 const double eps = 1e-9;
 33 const int mod = 1e9 + 7;
 34 const int maxn = 1000000 + 7;
 35 const double pi = acos(-1);
 36 const int inf = 0x3f3f3f3f;
 37 const LL INF = 0x3f3f3f3f3f3f3f3fLL;
 38 
 39 int n;
 40 int a[maxn];
 41 
 42 struct dir {
 43     int val, id;
 44     bool operator < (const dir& x) const {
 45         return val < x.val;
 46     }
 47 }ha[maxn];
 48 
 49 struct node {
 50     int l, r;
 51     LL cnt;
 52 }segtree[maxn<<2];
 53 
 54 void push_up(int rt) {
 55     segtree[rt].cnt = segtree[lson].cnt + segtree[rson].cnt;
 56 }
 57 
 58 void build(int rt, int l, int r) {
 59     segtree[rt].l = l, segtree[rt].r = r;
 60     segtree[rt].cnt = 0;
 61     if(l == r) return;
 62     int mid = (l + r) >> 1;
 63     build(lson, l, mid);
 64     build(rson, mid + 1, r);
 65 }
 66 
 67 void update(int rt, int x) {
 68     if(segtree[rt].l == x && segtree[rt].r == x) {
 69         segtree[rt].cnt++;
 70         return;
 71     }
 72     int mid = (segtree[rt].l + segtree[rt].r) >> 1;
 73     if(x <= mid) update(lson, x);
 74     else update(rson, x);
 75     push_up(rt);
 76 }
 77 
 78 LL query(int rt, int l, int r) {
 79     if(segtree[rt].l == l && segtree[rt].r == r) {
 80         return segtree[rt].cnt;
 81     }
 82     int mid = (segtree[rt].l + segtree[rt].r) >> 1;
 83     if(r <= mid) return query(lson, l, r);
 84     else if(l > mid) return query(rson, l, r);
 85     else return query(lson, l, mid) + query(rson, mid + 1, r);
 86 }
 87 
 88 int main() {
 89     scanf("%d", &n);
 90     for(int i = 1; i <= n; i++) {
 91         scanf("%d", &ha[i].val);
 92         ha[i].id = i;
 93     }
 94     sort(ha + 1, ha + n + 1);
 95     int t = 0, mx = -1;;
 96     for(int i = 1; i <= n; i++) {
 97         if(ha[i].val != ha[i-1].val) t++;
 98         a[ha[i].id] = t;
 99         mx = max(mx, a[ha[i].id]);
100     }
101     build(1, 1, mx);
102     LL ans = 0;
103     for(int i = 1; i <= n; i++) {
104         update(1, a[i]);
105         ans += i - query(1, 1, a[i]);
106     }
107     printf("%lld\n", ans);
108     return 0;
109 }

 

转载于:https://www.cnblogs.com/Dillonh/p/9709279.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值