【多校2018#2】HDU6318 Swaps and Inversions
题面在这里
考虑交换一对原本构成逆序对的数,会将代价从x变为y
而交换次数恰好等于逆序对数
所以\(x<y\)不做任何交换
\(x>y\)交换所有逆序对
又一次无耻的copy队友代码……
示例程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| #include<cstdio> #include<cctype> #include<algorithm> using namespace std; typedef long long LL; const int maxn=100000;
int n,X,Y,a[maxn+5],b[maxn+5],c[maxn+5];LL ans;
#define Eoln(x) ((x)==10||(x)==13||(x)==EOF) inline char readc(){ static char buf[100000],*l=buf,*r=buf; if (l==r) r=(l=buf)+fread(buf,1,100000,stdin); if (l==r) return EOF;return *l++; } inline int readi(int &x){ int tot=0;char ch=readc(),lst='+'; while (!isdigit(ch)) {if (ch==EOF) return EOF;lst=ch;ch=readc();} while (isdigit(ch)) tot=(tot<<3)+(tot<<1)+(ch^48),ch=readc(); return (lst=='-'?x=-tot:x=tot),Eoln(ch); } inline int Find(int x){ int L=1,R=b[0],mid; while (L<=R) {mid=L+(R-L>>1);if (b[mid]==x) return mid;x<b[mid]?R=mid-1:L=mid+1;} } inline void Update(int x,int tem) {for (int i=x;i<=b[0];i+=i&-i) c[i]+=tem;} inline int Sum(int x) {int sum=0;for (int i=x;i;i-=i&-i) sum+=c[i];return sum;} int main(){ while (~readi(n)){ readi(X);readi(Y);for (int i=1;i<=n;i++) readi(a[i]),b[i]=a[i]; sort(b+1,b+1+n);b[0]=unique(b+1,b+1+n)-b-1;ans=0; for (int i=1;i<=n;i++) a[i]=Find(a[i]),c[i]=0; for (int i=n;i;i--) ans+=Sum(a[i]-1),Update(a[i],1); if (X<Y) ans*=X; else ans*=Y;printf("%lld\n",ans); } return 0; }
|