今天学习了离散化存储老师留的课后作业就是杭电4911
是个模版题目
题意就是
有n个数,交换相邻的元素最多k次,最少的逆序数是多少?
这道题就是树状数组求逆序数,lowbit update sum写着就可以了
同时因为测试用例a[i]的值很大,不能直接用来当下标,所以需要对他进行离散化处理。
因为排序的时候顺序只和他们之间的相对大小有关,和具体的值是无关的。
先对数组进行排序,删除重复元素,留下的就是索引元素离散化后对应的值
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long int
using namespace std;
const int maxn=1e5+5;
int c[maxn];
int lisan[maxn];
int s[maxn];
int n,k;
int lowbit(int x){
return x&(-x);
}
void update(int i,int ans){
while(i<=n){
c[i]+=ans;
i+=lowbit(i);
}
}
int sum(int i){
int s=0;
while(i>0){
s+=c[i];
i-=lowbit(i);
}
return s;
}
int main(){
while(~scanf("%d%d",&n,&k)){
memset(c,0,sizeof(c));
for(int i=0;i<n;i++){
scanf("%d",&s[i]);
lisan[i]=s[i];
}
sort(lisan,lisan+n);
int len=unique(lisan,lisan+n)-lisan;
ll res=0;
for(int i=0;i<n;i++){
//TODO
ll l=lower_bound(lisan,lisan+len,s[i])-lisan+1;
update(l,1);
res+=i+1-sum(l);
}
if(res<k)printf("0\n");
else
printf("%lld\n",res-k);
}
return 0;
}
我不得不说这里面真的是有脏东西,死活不能提交,明明和老师一样的
然后在数组处标上注释这题就AC了...
真的很怪异,最近提交经常403 T T
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long int
using namespace std;
const int maxn=1e5+5;
int c[maxn];
int lisan[maxn];//用来存离散后的结果数组
int s[maxn];//用来存原始状态
int n,k;
int lowbit(int x){
return x&(-x);
}
void update(int i,int ans){
while(i<=n){
c[i]+=ans;
i+=lowbit(i);
}
}
int sum(int i){
int s=0;
while(i>0){
s+=c[i];
i-=lowbit(i);
}
return s;
}
int main(){
while(~scanf("%d%d",&n,&k)){
memset(c,0,sizeof(c));
for(int i=0;i<n;i++){
scanf("%d",&s[i]);
lisan[i]=s[i];
}
sort(lisan,lisan+n);
int len=unique(lisan,lisan+n)-lisan;
ll res=0;
for(int i=0;i<n;i++){
//TODO
ll l=lower_bound(lisan,lisan+len,s[i])-lisan+1;
update(l,1);
res+=i+1-sum(l);
}
if(res<k)printf("0\n");
else
printf("%lld\n",res-k);
}
return 0;
}