您的位置:首页 > 其它

ssoj1046密码pasuwado(树状数组+暴力)

2015-09-12 14:40 274 查看

题目描述

哪里有压迫,哪里就有反抗。
moreD的宠物在法庭的帮助下终于反抗了。作为一只聪明的宠物,他打算把魔法使moreD的魔法书盗去,夺取moreD的魔法能力。但moreD怎么会让自己的魔法书轻易地被盗取?moreD在魔法书上设置了一个密码锁,密码锁上有一个问题。
施以斯卧铺魔法吧,你有M次机会,如此将得完美密码。
然后是一串小写字母串。
moreD的宠物斯卧铺魔法就是施法时的字符串其中相邻两位交换
而moreD对于完美密码的定义自然是最小字典序了。
请帮助moreD的宠物,想出密码吧。

输入

第一行一个整数M,表示操作次数。

第二行一串小写字母组成的字符串S,如题目所示。

输出

输出完美密码。

样例输入

3dcba

样例输出

adcb

提示

【数据范围】

对于30%的数据|S|≤10

对于60%的数据|S|≤3,000

对于100%的数据8≤|S|≤100,000 M≤(|S|-8)^2+2

【后记】

宠物最终战胜了moreD,和自己的宠物快乐地生活着。

【样例解释】

先对第3,4两位施法,字符串变成dcab,然后对第2,3两位施法,字符串变成dacb,最后对第1,2两位施法,字符串变成adcb。

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#define ll long long
using namespace std;
const int maxn=100005;
const int cn=96;
int len,fst[31],nxt[maxn];
ll sm,n,sum[maxn];
char s[maxn];
inline ll lowbit(ll x){
return (ll)(x&-x);
}
inline void add(ll x,ll v){
while(x<len){
sum[x]+=v;
x+=lowbit(x);
}
}
inline ll getsum(ll x){
ll ans=0;
while(x){
ans+=sum[x];
x-=lowbit(x);
}
return ans;
}
int main(){
memset(fst,0,sizeof(fst));
memset(nxt,0,sizeof(nxt));
scanf("%lld",&n);
scanf("%s",s+1);
len=strlen(s+1);
for(int i=len;i>=1;--i)nxt[i]=fst[s[i]-cn],fst[s[i]-cn]=i;
for(int i=1;i<=len;++i)add(i,1);
for(int i=1;i<=len;++i){
int j;
for(j=1;j<=26;++j){
int pos=fst[j];
if(pos==0)continue;
sm=getsum(pos-1);
if(n>=sm){
n-=sm;
add(pos,-1);
fst[j]=nxt[pos];
printf("%c",j+cn);
break;
}
}
}
return 0;
}


思路:贪心,每次把能加到的最小的往前加。直接暴力会超时,用树状数组维护。

注意:n要用long long还有读入要记得修改!TAT
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: