10pts 求调玄关
查看原帖
10pts 求调玄关
1285357
jinminghao楼主2025/6/29 12:25

rt.

本蒟蒻的代码思路正确,能过很多测试点,但是WA,有的时候竟然输出负数,答案不会超过 long long。

请诸位大佬帮忙 ヾ(•ω•`)o

代码:

#include<cstdio>
#include<cmath>
using namespace std;
typedef long long LL;
const int N=3e5+10;
const long double eps=8e-18;
int a[N],n,q;
LL sum[N],g[N],c[N];
bool check(LL x,LL y,LL a,LL b) {
    if(x==0) return a<=0;
    if(a==0) return x>=0;
    long double log_x=log2(x);
    long double log_a=log2(a);
    return (log_x+(long double)y)-(log_a+(long double)b)>-eps;
}
int main(){
//	freopen("P12646_7.in","r",stdin);
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		c[i]=a[i];
	}
	for(int i=2;i<=n;i++){
		int l=0,r=g[i-1]+31;
		while(l<=r){
			int mid=l+r>>1;
			if(check(a[i],mid,a[i-1],g[i-1])){
				g[i]=mid;
				r=mid-1;
			}else{
				l=mid+1;
			}
		}
		sum[i]=sum[i-1]+g[i];
	}
	while(q--){
		int l,r;
		scanf("%d%d",&l,&r);
		if(l==r){
			puts("0");
			continue;
		}
		LL u=a[l+1],cnt=0;
		int ll=0,rr=g[l+1]+31;
		while(ll<=rr){
			int mid=ll+rr>>1;
			if(check(u,mid,a[l],0)){
				cnt=mid;
				rr=mid-1;
			}else{
				ll=mid+1;
			}
		}
		LL k=g[l+1]-cnt;
		LL ans=sum[r]-sum[l]-k*1ll*(r-l);
		printf("%lld\n",ans);
	}
	return 0;
}
2025/6/29 12:25
加载中...