二分:[BJWC2008]秦腾与教学评估

洛谷传送门
在这里插入图片描述在这里插入图片描述

解析

因为至多有一个单数
假设其位置为k,1-i的累加和为s[i]
则s[1]-s[k-1]全是偶数
s[k]-s[max]全是奇数
答案呈单调性,可以用二分算法
check函数(计算前缀和)也很容易用O(n)写出:

long long check(int x){
	long long tot=0;
	for(int i=1;i<=n;i++){
		if(p[i].b<=x){
			tot += (p[i].b-p[i].a)/p[i].m+1;
		}
		else if(p[i].a>x) continue;
		else{
			tot += (x-p[i].a)/p[i].m+1;
		}
	}
	return tot;
}

(时间复杂度应该可以更优,但这样够了,大脑就不想动了。。。)
两个地方要加1,因为排头有一个,之后的个数这是长度除间隔的地板除法
然后二分枚举位置判断奇偶即可

PS:不开longlong见祖宗

代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<string>
#include<queue>
#include<vector>
using namespace std;
const int M=1e9;
long long n,t;
long long mx=0;
struct node{
	long long a,b,m;
}p[200500];
long long check(int x){
	long long tot=0;
	for(int i=1;i<=n;i++){
		if(p[i].b<=x){
			tot += (p[i].b-p[i].a)/p[i].m+1;
		}
		else if(p[i].a>x) continue;
		else{
			tot += (x-p[i].a)/p[i].m+1;
		}
	}
	return tot;
}
int main(){
	scanf("%lld",&t);
	for(int k=1;k<=t;k++){
		mx=0;
		scanf("%lld",&n); 
		for(int i=1;i<=n;i++){
			scanf("%lld%lld%lld"
			,&p[i].a,&p[i].b,&p[i].m);
			mx=max(mx,p[i].b);
		}
		long long st=0,ed=mx+1;
		while(st<ed){
			long long mid=(st+ed) >> 1;
			if(check(mid)%2==1) ed=mid;
			else st=mid+1;
		}
		if(st==mx+1){
		//返回mx+1,说明全是偶数,无懈可击
			printf("Poor QIN Teng:( \n");
			continue;
		}
		printf("%lld %lld\n",st,check(st)
		-check(st-1));
	}
	return 0;
}

AC快乐!!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值