• Luogu P4403 秦腾与教学评估 题解报告


    题目传送门

    【题目大意】

    【思路分析】

     个人感觉这题挺妙的,一开始没看出来是二分,但有了二分的思路之后就很简单了。

    首先看到这题第一反映想到暴力,直接开数组统计每个位置的人数,但是这样数组就太大了,所以我们考虑用函数$cal(x)$表示位置$1~x$之间的总人数。因为已知人数为奇数的位置要么没有,要么只有一个,所以先找到左右边界,算出$mid$和$cal(mid)$,如果$cal(mid)$为奇数,则符合要求的位置在$l~mid$之间,否则在$mid+1~r$之间。还要注意一开始先算一下$cal(r)$,若为偶数,则不存在满足条件的位置。

    【代码实现】

     1 #include<cstdio>
     2 #include<iostream>
     3 #define rg register
     4 #define ll long long
     5 #define go(i,a,b) for(rg ll i=a;i<=b;i++)
     6 using namespace std;
     7 const int N=200002;
     8 ll T,n,S[N],D[N],E[N],pos,num;
     9 ll cal(ll d){
    10     ll s=0;
    11     go(i,1,n){
    12         if(S[i]>d) continue;
    13         s+=(min(E[i],d)-S[i])/D[i]+1;
    14     }
    15     return s;
    16 }
    17 int main(){
    18     scanf("%lld",&T);
    19     while(T--){
    20         scanf("%lld",&n);
    21         ll maxn=0;
    22         ll minn=1e9;
    23         go(i,1,n){
    24             scanf("%lld%lld%lld",&S[i],&E[i],&D[i]);
    25             maxn=max(maxn,E[i]);
    26             minn=min(minn,S[i]);
    27         }
    28         if(cal(maxn)%2==0) {printf("Poor QIN Teng:(
    ");continue;}
    29         ll l=minn,r=maxn;
    30         while(l<r){
    31             ll mid=(l+r)/2;
    32             if(cal(mid)%2!=0) r=mid;
    33             else l=mid+1;
    34         }
    35         printf("%lld %lld
    ",l,cal(l)-cal(l-1));
    36     }
    37     return 0;
    38 }
    代码戳这里
  • 相关阅读:
    巧用css实现强制不换行、自动换行、强制换行(转)
    解决IE6最后一行文字溢出
    CSS控制透明度
    中兴ZTEU880刷机
    ADO.NET Entity Framework AtaGlance
    低版本的IE浏览器position:relative跟随滚动条滚动解决方案
    ObjectARX ads_point 和AcGePoint3d 的转化
    ObjectARX代码片段三
    创建AcDb2dPolyline实体
    数据库处理
  • 原文地址:https://www.cnblogs.com/THWZF/p/11262859.html
Copyright © 2020-2023  润新知