BZOJ 4769: 超级贞鱼 归并排序
2017-07-27 09:50
459 查看
4769: 超级贞鱼
Time Limit: 2 Sec Memory Limit: 64 MBSubmit: 123 Solved: 32
[Submit][Status][Discuss]
Description
马达加斯加贞鱼是一种神奇的双脚贞鱼,它们把自己的智慧写在脚上--每只贞鱼的左脚和右脚上个有一个数。有一天,K只贞鱼兴致来潮,排成一列,从左到右第i只贞鱼会在右脚写Ai,左脚上写上i,第二年,这K只贞鱼按右脚的数从小到大排成一列,然后,它们决定重编号,从左到右第i只贞鱼会在右脚上写上左脚的数,在左脚上写i,第三年,它们按第二年的方法重排列、重编号......N年后,对于从左到右第i和第j贞鱼,若i<j且第i只贞鱼右脚上的数比第j只贞鱼右脚上的数大,则称它们为一对"超级贞鱼"。问一共有多少对"超级贞鱼"。Input
一共3行,第一行一个正整数K,第二行K个数从左到右输入Ai,第三行一个正整数N。1≤Ai≤10^9,1≤K≤5*10^6,0≤N≤5000
Output
一个整数,表示"超级贞鱼"对数。Sample Input
65 2 6 3 1 7
0
Sample Output
7模拟一下过程就会发现就是两个数列交替出现
根据m的奇偶性,把数列搞出来
之后求一遍逆序对就行了
#include<cmath> #include<ctime> #include<cstdio> #include<cstring> #include<cstdlib> #include<complex> #include<iostream> #include<algorithm> #include<iomanip> #include<vector> #include<string> #include<bitset> #include<queue> #include<map> #include<set> using namespace std; typedef long long ll; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*f; } void print(ll x) {if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');} const int N=1000100; struct P{int x,y;}b ; inline bool cmp(const P &x,const P &y) {return x.x==y.x?x.y<y.y:x.x<y.x;} int tmp ,a ,n,m; ll ans; void merger_sort(int l,int r) { if(l==r)return ; int mid=(l+r)>>1; merger_sort(l,mid);merger_sort(mid+1,r); register int i=l,j=mid+1,cnt=l-1; while(i<=mid&&j<=r) { while(a[i]>a[j]) {tmp[++cnt]=a[j++];ans+=mid-i+1;if(j>r)break;} tmp[++cnt]=a[i++]; } for(;i<=mid;++i)tmp[++cnt]=a[i]; for(;j<=r;++j)tmp[++cnt]=a[j]; for(i=l;i<=r;++i)a[i]=tmp[i]; } int main() { n=read(); register int i; for(i=1;i<=n;++i)b[i].x=read(),b[i].y=i; sort(b+1,b+1+n,cmp); m=read(); if(m&1)for(i=1;i<=n;++i)a[b[i].y]=i; else for(i=1;i<=n;++i)a[i]=b[i].y; merger_sort(1,n); print(ans);puts("");return 0; } /* 6 5 2 6 3 1 7 0 7 */
就在刚才。。。发现。。。
其实m的限制毫无卵用,直接求逆序对就好了。。。
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<complex>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<bitset>
#include<queue>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
void print(ll x)
{if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');}
const int N=1000100;
int tmp
,a
,n,m;
ll ans;
void merger_sort(int l,int r)
{
if(l==r)return ;
int mid=(l+r)>>1;
merger_sort(l,mid);merger_sort(mid+1,r);
register int i=l,j=mid+1,cnt=l-1;
while(i<=mid&&j<=r)
{
while(a[i]>a[j])
{tmp[++cnt]=a[j++];ans+=mid-i+1;if(j>r)break;}
tmp[++cnt]=a[i++];
}
for(;i<=mid;++i)tmp[++cnt]=a[i];
for(;j<=r;++j)tmp[++cnt]=a[j];
for(i=l;i<=r;++i)a[i]=tmp[i];
}
int main()
{
n=read();
register int i;
for(i=1;i<=n;++i)a[i]=read();
m=read();
merger_sort(1,n);
print(ans);puts("");
return 0;
}
/*
6
5 2 6 3 1 7
0
7
*/
相关文章推荐
- bzoj 4769: 超级贞鱼 -- 归并排序
- 【BZOJ4769】超级贞鱼 归并排序求逆序对
- bzoj1081 [SCOI2005]超级格雷码
- bzoj 4417: [Shoi2013]超级跳马
- 【bzoj1081】[SCOI2005]超级格雷码
- 【BZOJ4417】[Shoi2013]超级跳马 矩阵乘法
- bzoj 4417: [Shoi2013]超级跳马(矩阵合并+快速幂)
- [bzoj 1081--SCOI2005]超级格雷码
- [BZOJ 1081] [SCOI2005] 超级格雷码 【找规律】
- 【bzoj1191】【HNOI2006】【超级英雄】【Hero】【二分图匹配】
- [BZOJbegin][NOIP十连测第三场]平均数(二分+归并排序求逆序对)
- 【bzoj 十连测】[noip2016十连测第三场]Problem A: 平均数(二分答案+归并排序求逆序对)
- bzoj千题计划162:bzoj2006: [NOI2010]超级钢琴
- BZOJ 2006超级钢琴
- 【bzoj1081】[SCOI2005]超级格雷码
- BZOJ 3731: Gty的超级妹子树
- BZOJ1081 超级格雷码 [找规律]
- [块状树] BZOJ 3731 Gty的超级妹子树
- BZOJ 1191 [HNOI2006] 超级英雄 Hero 题解与分析
- BZOJ 2006 [NOI2010]超级钢琴