luogu P1966 火柴排隊 (逆序對)
阿新 • • 發佈:2018-09-29
amp void 貪心 cpp ble print bool () 一個
luogu P1966 火柴排隊
題目鏈接:https://www.luogu.org/problemnew/show/P1966
顯然貪心的想,排名一樣的數相減是最優的.
證明也很簡單.
此處就不證明了.
然後交換的話就是求一個逆序對.
怎麽樣排序是一個關鍵.
\(c\)數組的下標是\(a\)的排名,值是\(b\)的值.
這樣求逆序對的時候,就是排名為\(i\)的\(a\)數組,會對應上相應排名的\(b\)數組的上.
這也算是一個小技巧吧.
#include <algorithm> #include <iostream> #include <cstdio> using namespace std; const int maxN = 100000 + 7; const int mod = 99999997; int n; int f[maxN]; struct Node { int id,w; }a[maxN],b[maxN]; int c[maxN]; int ans; inline int read() { int x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();} return x * f; } bool cmp(Node a,Node b) { return a.w < b.w; } inline int lowbit(int x) {return x & -x;} void modify(int pos,int val) { while(pos <= n) f[pos] += val,pos += lowbit(pos); } int query(int pos) { int sum = 0; while(pos) sum += f[pos],pos -= lowbit(pos); return sum; } void re_pair1() { for(int i = 1;i <= n;++ i) { modify(c[i],1); ans += query(n) - query(c[i]); ans %= mod; } printf("%d", ans); return ; } int main() { n = read(); for(int i = 1;i <= n;++ i) a[i].id = i,a[i].w = read(); for(int i = 1;i <= n;++ i) b[i].id = i,b[i].w = read(); sort(b + 1,b + n + 1,cmp); sort(a + 1,a + n + 1,cmp); for(int i = 1;i <= n;++ i) c[a[i].id] = b[i].id; re_pair1(); return 0; }
luogu P1966 火柴排隊 (逆序對)