online judge:51nod-1364label:線段樹,樹狀陣列,二分
根據題意很容易想到60%資料的\(o(n^2logn)\)暴力做法,即每次從大數往小數找,如果它能在m步內換到當前位置就把它換到前面去,然後再把選中的位置設為0,可以用樹狀陣列在\(o(logn)\)完成。
對於100%資料考慮優化,思路還是一樣的。cin>>n;
for(int i=1;i<=n;i++)
for(int i=1;i<=n;i++)}}
這個做法還是比較無腦的,樹狀陣列存某一位前面還剩餘的數字個數,線段樹存序列中某段區間還留著的數字的最大值,但好打是重點,由於還巢狀了二分查詢,時間複雜度為\(o(n*logn*logn)\)。
所以只要乙個線段樹就好了,維護兩個東西,區間個數s、區間最值mx。時間複雜度為\(o(nlogn)\)。#includeusing namespace std;
const int n=1e5+10;
struct nodeb[n<<2];
int n,m;
int a[n],id[n],ans[n],c[n];
inline int lowbit(int x)
void add(int x,int d)
}int sum(int x)
return ret;
}void build(int l,int r,int o)
int mid=l+r>>1;
build(l,mid,o<<1);
build(mid+1,r,o<<1|1);
b[o].w=max(b[o<<1].w,b[o<<1|1].w);
}void update(int o,int pos,int d)
int mid=b[o].l+b[o].r>>1;
if(pos<=mid)update(o<<1,pos,d);
else update(o<<1|1,pos,d);
b[o].w=max(b[o<<1].w,b[o<<1|1].w);
}int query(int l,int r,int o)
int main()
int p=query(1,lim,1);//線段樹找
update(1,id[p],0);//線段樹單點修改
m-=(sum(id[p])-1);
add(id[p],-1);
ans[i]=p;
}
for(int i=1;i<=n;i++)printf("%d\n",ans[i]);
}
**如下☞
#includeusing namespace std;
typedef long long ll;
const int n=1e5+10;
#define for(a,b,c) for(register int a=b;a<=c;a++)
inline int read()
int s[n<<2],mx[n<<2],pos[n],id[n],m,n;
void build(int o,int l,int r)
int mid=l+r>>1;
build(o<<1,l,mid),build(o<<1|1,mid+1,r);
mx[o]=max(mx[o<<1],mx[o<<1|1]);
s[o]=s[o<<1]+s[o<<1|1];
}void update(int o,int l,int r,int pos,int co)
int mid=l+r>>1;
if(pos<=mid)update(o<<1,l,mid,pos,co);
else update(o<<1|1,mid+1,r,pos,co+s[o<<1]);
mx[o]=max(mx[o<<1],mx[o<<1|1]);
s[o]=s[o<<1]+s[o<<1|1];
}int query(int o,int l,int r,int d)
int main()
}
51nod1364 最大字典序排列
給出乙個1至n的排列,允許你做不超過k次操作,每次操作可以將相鄰的兩個數交換,問能夠得到的字典序最大的排列是什麼?例如 n 5,k 6,在6次交換後,能夠得到的字典序最大的排列為。input 第1行 2個數n,k中間用空格分隔 1 n 100000,0 k 10 9 第2至n 1行 每行乙個數i 1...
51nod 1364 最大字典序排列
給出乙個1至n的排列,允許你做不超過k次操作,每次操作可以將相鄰的兩個數交換,問能夠得到的字典序最大的排列是什麼?例如 n 5,k 6,在6次交換後,能夠得到的字典序最大的排列為。input 第1行 2個數n,k中間用空格分隔 1 n 100000,0 k 10 9 第2至n 1行 每行乙個數i 1...
51nod 1364 最大字典序排列 線段樹
原題鏈結 1364 最大字典序排列 基準時間限制 1 秒 空間限制 131072 kb 分值 80 難度 5級演算法題 給出乙個1至n的排列,允許你做不超過k次操作,每次操作可以將相鄰的兩個數交換,問能夠得到的字典序最大的排列是什麼?例如 n 5,k 6,在6次交換後,能夠得到的字典序最大的排列為。...