【HDOJ6318】Swaps and Inversions(树状数组)
题意:
给定一串数组,其中含有一个逆序对则需要花费x,交换相邻两个数需要花费y,输出最小花费。
n<=1e5,-1e9<=a[i]<=1e9
思路:
1 #include<cstdio> 2 #include<cstring> 3 #include<string> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<vector> 11 using namespace std; 12 typedef long long ll; 13 typedef unsigned int uint; 14 typedef unsigned long long ull; 15 typedef pair<int,int> PII; 16 typedef vector<int> VI; 17 #define fi first 18 #define se second 19 #define MP make_pair 20 const int N=110000; 21 22 int n,m,x,y,a[N],b[N],c[N]; 23 ll ans; 24 25 int read() 26 { 27 int v=0,f=1; 28 char c=getchar(); 29 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 30 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 31 return v*f; 32 } 33 34 int query(int x) 35 { 36 int ans=0; 37 for(;x;x-=x&-x) ans+=c[x]; 38 return ans; 39 } 40 41 void update(int x) 42 { 43 for(;x<=m;x+=x&-x) c[x]++; 44 } 45 46 int main() 47 { 48 49 while(scanf("%d%d%d",&n,&x,&y)!=EOF) 50 { 51 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 52 for(int i=1;i<=n;i++) b[i]=a[i]; 53 sort(b+1,b+n+1); 54 m=unique(b+1,b+n+1)-b-1; 55 for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+m+1,a[i])-b; 56 ans=0; 57 memset(c,0,sizeof(c)); 58 for(int i=n;i>=1;i--) 59 { 60 ans+=query(a[i]-1); 61 update(a[i]); 62 } 63 ans=ans*min(x,y); 64 printf("%lld\n",ans); 65 } 66 return 0; 67 } 68 69
null