标签:its lan txt problem cond open can 就是 hid
题意:只有2种走路方式,往右或者往下,求先走到一个大的数,在走到小的数的这种方式有多少。也就是说求出关于这个2维矩阵的逆序数。
题解:二维数组+逆序数就完事了。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); 4 #define LL long long 5 #define ULL unsigned LL 6 #define fi first 7 #define se second 8 #define pb push_back 9 #define lson l,m,rt<<1 10 #define rson m+1,r,rt<<1|1 11 #define max3(a,b,c) max(a,max(b,c)) 12 #define min3(a,b,c) min(a,min(b,c)) 13 typedef pair<int,int> pll; 14 const int INF = 0x3f3f3f3f; 15 const LL mod = 1e9+7; 16 const int N = 1e5+10; 17 struct Node{ 18 int a, id; 19 int x, y; 20 }A[305*305]; 21 bool cmp(Node x1, Node x2){ 22 if(x1.a == x2.a) return x1.id > x2.id; 23 return x1.a > x2.a; 24 } 25 int lowbit(int x){ 26 return x&(-x); 27 } 28 int n, m; 29 LL tree[305][305]; 30 void update(int x, int y){ 31 for(int i = x; i <= n; i+=lowbit(i)) 32 for(int j = y; j <= m; j += lowbit(j)) 33 tree[i][j]++; 34 } 35 LL query(int x, int y){ 36 LL ret = 0; 37 for(int i = x; i; i-=lowbit(i)) 38 for(int j = y; j; j-=lowbit(j)) 39 ret += tree[i][j]; 40 return ret; 41 } 42 int main(){ 43 ///Fopen; 44 scanf("%d%d", &n, &m); 45 int t = 0; 46 for(int i = 1; i <= n; i++) 47 for(int j = 1; j <= m; j++){ 48 t++; 49 scanf("%d", &A[t].a); 50 A[t].x = i; 51 A[t].y = j; 52 A[t].id = t; 53 // cout <<‘s‘ <<A[i].id << endl; 54 } 55 sort(A+1, A+1+t, cmp); 56 LL ans = 0; 57 for(int i = 1; i <= t; i++){ 58 //cout << A[i].id << ‘ ‘ << A[i].x << ‘ ‘ << A[i].y << endl; 59 ans += query(A[i].x,A[i].y); 60 update(A[i].x, A[i].y); 61 } 62 printf("%I64d", ans); 63 return 0; 64 }
Another Version of Inversion 二维树状数组求逆序对
标签:its lan txt problem cond open can 就是 hid
原文地址:https://www.cnblogs.com/MingSD/p/9108555.html