ABC346_C Σ
整体思路:二分+排序+数学
错误代码1如下
#include<bits/stdc++.h>
using namespace std;
long long n,k,a[200001];
int main(){
cin.tie(0)->sync_with_stdio(0);
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1);
unique(a+1,a+n+1);
int x=lower_bound(a+1,a+n+1,k)-a-1;
long long sum=0;
for(int i=1;i<=x;i++) sum+=a[i];
cout<<(k+1)*k/2-sum<<endl;
}
一眼出来思路,但是没有考虑全面。
题目中只是说:"All input values are integers",没有说正还是负。但是我默认是正的,WA了7个点
其实是二分出两个分界线,左边的界限是划分1和≤1的,r和r右边是合法的,l和l左边是不合法的。
右边的分界线同理(其实不同里,待会儿会讲)
我以为这个代码是对的时候,它还是WA了2个点
错误代码2如下
#include<bits/stdc++.h>
using namespace std;
long long n,k,a[200001];
long long cnt=0,b[200001];
unordered_map<int,int> v;
int main(){
cin.tie(0)->sync_with_stdio(0);
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1);
for(int i=1;i<=n;i++){
if(!v[a[i]]) b[++cnt]=a[i];
v[a[i]]=1;
}
int x=lower_bound(b+1,b+cnt+1,k)-b-1;
int y=lower_bound(b+1,b+cnt+1,1)-b;
long long sum=0;
for(int i=y;i<=x;i++) sum+=b[i];
cout<<(k+1)*k/2ll-sum<<endl;
}
我为什么不对?
问题在于lower_bound。
我的x求的是小于k的最后一个数,当时想的是如果没有k,那么lower_bound和upper_bound是同理的,但是我以为有k也是这样的,只不过下面计算的时候会抵消掉,然而并不是。
其实如果在计算x的时候还要再-1就是错的。不管怎么样,程序都会认为没有看k。导致有k的时候,会把k多计算。
所以要分成两种情况分类讨论。
一种是没有k,那么x要-1
一种是有k,那么x不变
终于这个题目改对了
代码如下
#include<bits/stdc++.h>
using namespace std;
long long n,k,a[200001];
long long cnt=0,b[200001];
unordered_map<int,int> v;
int main(){
cin.tie(0)->sync_with_stdio(0);
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1);
for(int i=1;i<=n;i++){
if(!v[a[i]]) b[++cnt]=a[i];
v[a[i]]=1;
}
int x=lower_bound(b+1,b+cnt+1,k)-b;
int y=lower_bound(b+1,b+cnt+1,1)-b;
if(b[x]!=k) x--;
long long sum=0;
for(int i=y;i<=x;i++) sum+=b[i];
cout<<(k+1)*k/2ll-sum<<endl;
}

浙公网安备 33010602011771号