【JZOJ 3873】 乐曲创作
来源:互联网 发布:飞思卡尔单片机培训 编辑:程序博客网 时间:2024/04/29 01:22
Description
给出1~N的一个排列,求出一个排列使得其逆序对数等于原排列的逆序对数,且字典序比满足原序列大之下,使字典序尽量小
100%的数据,1≤N≤500000。
Analysis
这就是一道大构造+贪心
1.找出第一个需要改变的位置pos
该位置(设为pos)需要满足两个约束条件
- 其右边有比他大的数
- 其右边比他小的数的个数设为b,序列[pos+1,n]的逆序对数为a,则b+1<=a
尽量靠右
用树状数组很好维护
2.从pos往后做,依次求出a[pos+1~n]
假设1~i-1的a已经确定了,那么我们可以求出
k-1+(n-i)*(n-i-1)/2>=tot
tot为还剩下没累加的逆序对数,那做完了这一位之后tot-=k
于是可以找到一个最小的k,我们就查询一下第k大,可以统计一颗权值线段树,在线段树上二分
i往后移一格就在线段树里删除该点
nlogn
Code
#include<cstdio>#include<cstring>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,b,a) for(int i=b;i>=a;i--)#define min(x,y) ((x)<(y)?(x):(y))#define max(x,y) ((x)>(y)?(x):(y))using namespace std;typedef long long ll;const int N=500010;int st,BIT[N],tr[N*4],pos[N];ll n,tot,b[N],c[N],a[N],f[N];ll lowbit(ll x){ return x&-x;}ll get(ll x){ ll t=0; for(int i=x;i;i-=lowbit(i)) t+=BIT[i]; return t;}void add(ll x){ for(int i=x;i<=n;i+=lowbit(i)) BIT[i]++;}void change(int v,int l,int r,int x,ll z){ if(l==r) { tr[v]+=z; return; } int mid=(l+r)>>1; if(x<=mid) change(v+v,l,mid,x,z); else change(v+v+1,mid+1,r,x,z); tr[v]=tr[v+v]+tr[v+v+1];}ll find(int v,int l,int r,ll k){ if(l==r) return l; int mid=(l+r)>>1; if(tr[v+v]>=k) return find(v+v,l,mid,k); else return find(v+v+1,mid+1,r,k-tr[v+v]);}int main(){ scanf("%lld",&n); fo(i,1,n) scanf("%lld",&a[i]); ll mx=0; fd(i,n,1) { mx=max(mx,a[i]); b[i]=get(a[i]); f[i]=f[i+1]+b[i]; if(a[i]<mx && b[i]+1<=f[i] && !st) st=i; add(a[i]); } tot=f[1]; ll t=0;a[0]=N; fo(i,st+1,n) if(a[i]>a[st] && a[i]<a[t]) t=i; swap(a[st],a[t]); fo(i,st+1,n) change(1,1,n,a[i],1),pos[a[i]]=i; fo(i,1,st) printf("%lld ",a[i]); memset(BIT,0,sizeof(BIT)); fd(i,n,1) { b[i]=get(a[i]); add(a[i]); } fo(i,1,st) tot-=b[i]; fo(i,st+1,n) { ll t=(n-i)*(n-i-1)/2; ll k=max(1,min(tot-t+1,n-i+1)); tot-=k-1; ll x=find(1,1,n,k); printf("%lld ",x); ll p=pos[x]; pos[x]=i,pos[a[i]]=p; swap(a[i],a[p]); change(1,1,n,a[i],-1); } return 0;}
0 0
- 【JZOJ 3873】 乐曲创作
- 乐曲创作
- 乐曲创作
- 乐曲创作
- jzoj. 3873. 【NOIP2014八校联考第4场第2试10.20】乐曲创作(music)
- jzoj 3873. 【NOIP2014八校联考第4场第2试10.20】乐曲创作(music) 构造题+树状数组+线段树
- 【NOIP2014八校联考】乐曲创作(music) (详细证明)
- 【JZOJ3873】【NOIP2014八校联考第4场第2试10.20】乐曲创作(music)
- 【NOIP2014八校联考第4场第2试10.20】乐曲创作
- 【JZOJ3873】【NOIP2014八校联考第4场第2试10.20】乐曲创作(music)
- 乐曲速度标记
- 汇编乐曲编程
- [COGS902]乐曲主题
- Matlab编写乐曲
- 乐曲识别(版本检测)
- 汇编语言实现乐曲程序实践
- 自我创作
- 论文创作
- Eclipse快捷键大全
- java并发编程(十五)----(线程池)java线程池简介
- linux命令大全
- 分支界限法 任务分配问题
- 小白求助!Repeater~FindControl【Checkbox】.checked;返回空值。
- 【JZOJ 3873】 乐曲创作
- Sicp第1章学习总结
- 玩儿透ELK日志分析集群搭建管理(rsyslog->kafka->Logstash->ES->Kibana)
- mysql主从复制详解
- LeetCode 485. Max Consecutive Ones(Java)
- 输出所有形如aabb的完全平方数(即前两位相等,后两位相等)
- POJ 1017解题报告
- G - Catch That Cow
- vue-cli 安装