【NOIP2014八校联考第4场第2试10.20】乐曲创作
来源:互联网 发布:sqlserver数据库安全 编辑:程序博客网 时间:2024/05/18 12:02
Description
小可可是音乐学院的一名学生,他需要经常创作乐曲完成老师布置的作业。
可是,小可可是一个懒惰的学生。所以,每次完成作业时,他不会重新创作一首新的乐曲,而是去修改上一次创作过的乐曲作为作业交给老师。小可可的乐曲由N个音调不同的音符组成,分别记为音符1…N。因此,他创作的乐曲是由1…N的一个排列构成,例如N=5时,他创作的乐曲可能为:2,1,3,5,4。但是,小可可每一次会按照一定的要求修改上一次创作的乐曲。他规定,修改过后的乐曲必须与上一次创作的乐曲的悦耳值相同。所谓悦耳值就是他所创作的乐曲,也就是1…N的排列中逆序对的个数。逆序对是指对于1…N的一个排列A1,A2,…,An中的两个数Ai,Aj,满足i
Solution
先求出逆序对sum
题目要求的最小字典序,所以要选一个位置p,然后前面保持不变,后面改掉。
那么这个位置要满足一些条件,首先是后面有一个比自己大的,然后就是第一个比自己大的先填后面全部倒着填(最好情况)不比sum小,全部正着填(最坏情况)不比sum大。
那么就找到这个位置了。把后面第一个比自己大的放过来。
然后每次二分填哪个数最优,用线段树查找第k大的数填来搞就好了。
Code
#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#include<math.h>#define fo(i,a,b) for(i=a;i<=b;i++)#define fod(i,a,b) for(i=a;i>=b;i--)using namespace std;const int maxn=5e5+7;typedef long long ll;int i,j,l,n,m,p;int a[maxn],f[maxn],ans[maxn],tr[maxn],r,mid,o,you[maxn];ll sum,b[maxn],len,op,k,zhi;struct node{ int num;}t[maxn*4];bool bz[maxn],az;int lowbit(int x){return x&(-x);}void add(int x,int y){ for(;x<=n;x+=lowbit(x))tr[x]+=y;}int find1(int x){ int z=0; for(;x;x-=lowbit(x))z+=tr[x]; return z;}void change(int x,int l,int r,int y,int z){ if(l==r){t[x].num+=z;return;} int mid=(l+r)/2; if(y<=mid)change(x*2,l,mid,y,z); else change(x*2+1,mid+1,r,y,z); t[x].num=t[x*2].num+t[x*2+1].num;}int find(int x,int l,int r,int y){ if(l==r)return l; int mid=(l+r)/2; if(y<=t[x*2].num)return find(x*2,l,mid,y); else return find(x*2+1,mid+1,r,y-t[x*2].num);}int main(){// freopen("fan.in","r",stdin);// freopen("fan.out","w",stdout); scanf("%d",&n); fo(i,1,n)scanf("%d",&a[i]); fod(i,n,1)you[i]=max(you[i+1],a[i]); fod(i,n,1){ f[i]=find1(a[i]);sum+=f[i]; add(a[i],1); } fo(i,1,n)b[i]=b[i-1]+f[i]; fod(i,n,1){ len=n-i+1; zhi=b[i-1]+len*(len-1)/2; if(zhi>=sum&&you[i]>a[i]&&b[i-1]+f[i]+1<=sum){ p=i; break; } } fo(i,1,p-1)ans[i]=a[i]; int u=0x7fffffff; fo(i,p+1,n)if(a[i]>a[p])u=min(u,a[i]); fo(i,p,n) if(a[i]!=u)change(1,1,n,a[i],1),op+=(a[i]<u); op+=b[p-1];ans[p]=u; fo(i,p+1,n){ l=1,r=n-i+1;len=r-1; while(l<r){ mid=(l+r)/2; o=find(1,1,n,mid); k=mid-1+len*(len-1)/2+op; if(k>=sum)r=mid;else l=mid+1; } ans[i]=find(1,1,n,l); op+=l-1; change(1,1,n,ans[i],-1); } fo(i,1,n)printf("%d ",ans[i]);}
1 0
- 【JZOJ3873】【NOIP2014八校联考第4场第2试10.20】乐曲创作(music)
- 【NOIP2014八校联考第4场第2试10.20】乐曲创作
- 【JZOJ3873】【NOIP2014八校联考第4场第2试10.20】乐曲创作(music)
- jzoj. 3873. 【NOIP2014八校联考第4场第2试10.20】乐曲创作(music)
- jzoj 3873. 【NOIP2014八校联考第4场第2试10.20】乐曲创作(music) 构造题+树状数组+线段树
- 【JZOJ3874】【NOIP2014八校联考第4场第2试10.20】准备复赛(exam)
- 【JZOJ3875】【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- JZOJ 3875. 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- 【NOIP2014八校联考第4场第2试10.20】准备复赛
- 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- 【JZOJ3875】【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- 高中OJ3874. 【NOIP2014八校联考第4场第2试10.20】准备复赛(exam)
- 【NOIP2014八校联考】乐曲创作(music) (详细证明)
- 【NOIP2014八校联考第2场第2试】单词接龙
- 【NOIP2014八校联考第2场第2试】帮助Bsny
- 【NOIP2014八校联考第2场第2试9.28】单词接龙
- 【NOIP2014八校联考第2场第2试9.28】帮助Bsny(help)
- 【NOIP2014八校联考第2场第2试9.28】分组(group)
- TensorFlow官方教程学习笔记(五)——前馈神经网络
- Linux 4.9.2 下添加系统调用
- 数论-素数
- Linux下./configure,make,make install的作用
- align-self
- 【NOIP2014八校联考第4场第2试10.20】乐曲创作
- POJ1003 solve Hangover
- 多线程的几种控制方式
- opencv将图片变成固定比例,多余部分黑色填充
- 给你的组件添加Label
- Yii2框架源码追踪阅读(一)--从入口脚本index.php到类加载器的初始化
- BaseAdapter封装优化
- STL之Map完整(Linux内核)内部实现
- 那些年我用awk时踩过的坑——awk使用注意事项