[luogu4403][bzoj1271][BJWC2008]秦腾与教学评估

时间:2020-12-26 22:21:00

题目描述

在秦腾进入北京大学学习的第一个学期,就不幸遇到了前所未有的教学评估。在教学评估期间,同学们被要求八点起床,十一点回宿舍睡觉,不准旷课,上课不准迟到,上课不准睡觉……甚至连著名的北大三角地也在教学评估期间被以影响校容的理由被拆除。这些“变态”规定令习惯了*自在随性生活学习的北大同学叫苦不迭。这一天又到了星期五,一大早就是秦腾最不喜欢的高等代数课。可是因为是教学评估时期,不能迟到,于是他在八点五分的时候挣扎着爬出了宿舍,希望能赶快混进在八点钟已经上课了的教室。可是,刚一出宿舍楼门他就傻眼了:从宿舍到教学楼的路上已经站满了教学评估团的成员。他们的目的就是抓住像他这样迟到的学生,扣除学校的分数。秦腾当然不能让评估团得逞。他经过观察发现,整个评估团分成了N个小组,每个小组的成员都分布在从宿舍楼到教学楼的路上的某一段,并且同一小组的成员间的距离是相等的。于是,我们可以用三个整数S,E,D来描述评估团的小组:既该小组的成员在从宿舍到教学楼的路上的:S,S+D,S+2D,…,S+KD(K∈Z,S+KD≤E,S+(K+1)D>E)位置。观察到了教学评估团的这一特点,又经过了认真的思考,秦腾想出了对策:如果在路上的某一位置有奇数个教学评估团成员,他就可以运用调虎离山,声东击西,隔山打牛,暗度陈仓……等方法,以这一地点为突破口到达教学楼。但是由于教学评估团的成员的十分狡猾,成员位置安排的设计极其精妙,导致在整条路上几乎没有这样的位置出现。即使由于安排不慎重出现了这样的位置,最多也仅有一个。现在秦腾观察出了所有小组的安排,但是由于整个教学评估团的人数太多,他实在看不出这样的位置是否存在。现在,你的任务是写一个程序,帮助他做出判断。

题目大意

求出奇数个标记的点

解法

因为只有一个点,那么在这个点之后所有点的前缀和都是奇数,那么也就是说我们需要找到的是位置是奇数的点的位置。
那么我们二分的答案就是这个点所在的位置,这里比较好理解。
前缀和,非常容易推导出公式是\((min(x,e[i])-t[i])/d[i]+1\)。
\(ps.\)不开\(longlong\)见祖宗。

ac代码

#include<bits/stdc++.h>
#define LL long long
#define N 200005
#define inf 0x3f3f3f3f
using namespace std;
int read(){
    int w=0,x=0;char ch=0;
    while(!isdigit(ch))w|=ch=='-',ch=getchar();
    while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    return w?-x:x;
}
int n;
LL e[N],s[N],d[N];
LL calc(LL x){
    LL res=0;
    for(int i=1;i<=n;i++)
        if(s[i]<=x) res=res+(min(e[i],x)-s[i])/d[i]+1;
    return res;
}
int main(){
    int cas=read();
    while(cas--){
        n=read();
        for(int i=1;i<=n;i++)s[i]=read(),e[i]=read(),d[i]=read();
        LL ans=0;
        LL l=0,r=2147483647;
        while(l<=r){
            LL mid=(l+r)>>1;
            if(calc(mid)%2) r=mid-1,ans=mid;
            else l=mid+1;
        }
        if(!ans)puts("Poor QIN Teng:(");
        else printf("%lld %lld\n",ans,calc(ans)-calc(ans-1));
    }
    return 0;
}