怀念一下归并+逆序对
2016-05-27 10:55
155 查看
/* codevs 4163 神犇与逆序对 */ #include<cstdio> #define ll long long #define maxn 1000010 using namespace std; ll n,a[maxn],b[maxn],ans; ll init() { ll x=0;char s;s=getchar(); while(s<'0'||s>'9')s=getchar(); while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} return x; } void Merge_sort(ll l,ll r) { if(l==r)return ; ll mid=(l+r)/2; Merge_sort(l,mid); Merge_sort(mid+1,r); ll i=l,j=mid+1,k=l; while(i<=mid&&j<=r) { if(a[i]>a[j]) { b[k++]=a[j++];ans+=mid-i+1; } else b[k++]=a[i++]; } while(i<=mid)b[k++]=a[i++]; while(j<=r)b[k++]=a[j++]; for(ll i=l;i<=r;i++)a[i]=b[i]; } int main() { n=init(); for(ll i=1;i<=n;i++) a[i]=init(); Merge_sort(1,n); printf("%lld\n",ans); return 0; }/*
/* codevs 3286 火柴排队 首先要知道两点 1:两列火柴高度排名大小相同时排列答案最优 2:移动两个序 列和移动一个序列步数一样 证明嘛 自己想吧 ^ ^ 假设我们只移动第二个序列 消耗步数就是求下逆序对 现在的问题就是求出第二个序列需要怎么移动 求逆序对我们想到用归并排序 那么移动的目标就是有序序列1-n 怎么和“两列火柴高度排名大小相同”联系起来呢 这样 我们维护a1 a2 p1 p2几个序列 a1[i]=j:原序列1中i位置处的高度排名 a2同理 p1[i]=j:原序列1中高度排名i的位置 那p1[a2[i]]就是原序列2中i位置处的高度排名那么大的在1中的位置 我们把这个位置记在p2[i]中 那就是需要把i移动到p2[i] 也就是逆序对的个数 */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define mod 99999997 #define maxn 2000020 using namespace std; int n,a1[maxn],a2[maxn],p[maxn],l[maxn],w[maxn]; long long ans; struct node { int o,h; }s1[maxn],s2[maxn]; int init() { int x=0;char s;s=getchar(); while(s<'0'||s>'9')s=getchar(); while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} return x; } int cmp(const node &x,const node &y) { return x.h<y.h; } void Merge(int l,int r) { if(l==r)return ; int mid=(l+r)/2; Merge(l,mid); Merge(mid+1,r); int i=l,j=mid+1,k=l; while(i<=mid&&j<=r) { if(p[i]>p[j]) { w[k++]=p[j++];ans=(ans+mid-i+1)%mod; } else w[k++]=p[i++]; } while(i<=mid)w[k++]=p[i++]; while(j<=r)w[k++]=p[j++]; for(int i=l;i<=r;i++)p[i]=w[i]; } int main() { n=init(); for(int i=1;i<=n;i++) { s1[i].h=init(); s1[i].o=i; } for(int i=1;i<=n;i++) { s2[i].h=init(); s2[i].o=i; } sort(s1+1,s1+1+n,cmp); sort(s2+1,s2+1+n,cmp); for(int i=1;i<=n;i++) { a1[s1[i].o]=i; a2[s2[i].o]=i; } for(int i=1;i<=n;i++) l[a1[i]]=i; for(int i=1;i<=n;i++) p[i]=l[a2[i]]; Merge(1,n); printf("%d\n",ans); return 0; }
相关文章推荐
- python resources collection
- MBus总线的基础学习
- 程序崩溃时生成Dump文件
- XAMPP的安装和PhpStrorm的配置
- Rotate List
- 查询EBS低效程序
- 金融支付名词解释
- python *args and **kwargs
- sqlplus工具基本使用
- MySQL数据库远程访问权限如何打开(两种方法)
- 【HR必看】Excel中对身份证号码的处理技巧
- tomcat 生成控制台日记到指定文件
- UIViewController的基本概念与生命周期
- java实现堆排序
- Android SystemUI源码分析(一)
- 档口主动工作
- Windows node.js npm install express -g Cannot find module 'express'
- QT设计UI:QT模式对话框打开文件
- PHP TP模板下的微信登录(PC)
- SpiderMonkey--VM栈设计