推公式(也有人二分过了)。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
int a,b;
cin>>a>>b;
if(b>a){
printf("-1");
return 0;
}
if(a==b){
printf("%d",a);
return 0;
}
int res=a/b;
double ans;
double A=(a+0.0)/b;
double B=1;
if(res&1){
ans=(A+B+0.0)/(res+1);
}else{
ans=(A+B+0.0)/(res);
}
printf("%.10f",ans*b);
return 0;
}
首先推出一个结论,肯定是全乘在一个数上最好,但这个数不一定是最大的数,枚举一下就行了。最好的做法是处理出前缀后缀,但是我没有那样做,比较繁琐。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int a[200010];
int tot[66];
bool bitcnt[200010][66];
int main(){
int n,k,x;
cin>>n>>k>>x;
for(int i=1;i<=n;i++){
scanf("%d",a+i);
for(int j=0;j<31;j++){
if(a[i]&(1<<j)){
bitcnt[i][j]=1;
tot[j]++;
}
}
}
ll kx=1;
while(k--){
kx*=x;
}
ll ans=0;
for(int i=1;i<=n;i++){
for(int j=0;j<31;j++){
tot[j]-=bitcnt[i][j];
}
ll A=kx*a[i];
for(int j=0;j<63;j++){
if(A&(1LL<<j)){
tot[j]++;
}
}
ll cur=0;
for(int j=0;j<63;j++){
if(tot[j]){
cur|=(1LL<<j);
}
}
ans=max(ans,cur);
for(int j=0;j<63;j++){
if(A&(1LL<<j)){
tot[j]--;
}
}
for(int j=0;j<31;j++){
tot[j]+=bitcnt[i][j];
}
}
cout<<ans<<endl;
return 0;
}
英文单词看得不太懂,但是可以看出来是让最大/最小子串和的绝对值相等。求最大/最小子串和问题无限经典,O(n)可以做出来。然后就会有一个朴素的想法,不断地调整,多扣少补,幅度越来越小,直到满足精度要求,反正我是类似二分的一发乱搞,居然过了。
听别人说用三分做,因为这肯定是个凹函数,我这个奇特的姿势和三分有异曲同工之妙吧。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
double a[200010];
int n;
int lenp,lenn;
double get_positive(){
double ans=0;
double cur=0;
int len=0;
for(int i=1;i<=n;i++){
cur+=a[i];
len++;
if(cur<0){
cur=0;
len=0;
}
if(cur>ans){
ans=cur;
lenp=len;
}
}
return ans;
}
double get_negative(){
double ans=0;
double cur=0;
int len=0;
for(int i=1;i<=n;i++){
cur+=a[i];
len++;
if(cur>0){
cur=0;
len=0;
}
if(cur<ans){
ans=cur;
lenn=len;
}
}
return -ans;
}
int main(){
cin>>n;
double Max=0;
for(int i=1;i<=n;i++){
scanf("%lf",a+i);
Max=max(Max,a[i]);
}
double P,N;
while(1){
P=get_positive();
N=get_negative();
if(fabs(P-N)<1e-6*0.8)break;
double adjust=fabs(P-N)/max(lenp,lenn)/4; //不要问我这个4怎么来的,只是凭感觉除以4比较合适。
if(P>N){
for(int i=1;i<=n;i++){
a[i]-=adjust;
}
}else{
for(int i=1;i<=n;i++){
a[i]+=adjust;
}
}
}
double ans=(P+N)/2;
printf("%.7f",ans);
return 0;
}