zoukankan      html  css  js  c++  java
  • hdu4768 非常规的二分

    题意:
          n个社团给同学发传单,同学一共有1--2^31这么多,每个社团有三个数A ,B ,C ,只有
    满足 A ,A + C ,A + C + C ...A + KC <= B 的学生才能得到传单,问你谁收到的传单数是奇数,题目保证给的测试数据要么没有奇数的,要么只有一个是奇数个传单.

    思路:

         "题目保证给的测试数据要么没有奇数的,要么只有一个是奇数个传单." ,这句非常关键,我们二分枚举1--2^31,对于mid,算出0--mid一共发出去tmp张传单,如果tmp是偶数那么奇数的那个人一定不会在前面,因为只有一个奇数,其他的都是偶数,奇数 + 偶数 = 奇数,偶数+ 偶数 = 偶数,所以可以根据当前的数是不是偶数就能断定奇数的那个人在不在mid前面.对于不存在的这个判定,我是前直接跑出所有的个数,也就是求出范围INF以前的所有,如果偶数那么就不存在,否则就二分找,找到后在枚举这个找到的人有多少个传单,输出来就行了.这个只是用二分的特性去节省时间,和以往的二分不同,因为他不是在单调函数上查找的.所以这个我感觉是一个非常规的二分.


    #include<stdio.h>
    
    #define N 20000 + 100
    
    typedef struct
    {
       __int64 A ,B ,C;
    }NODE;
    
    NODE node[N];
    
    
    __int64 minn(__int64 x ,__int64 y)
    {
       return x < y ? x : y;
    }
    
    __int64 solve(__int64 mid ,int n)
    {
       __int64 sum = 0;
       for(int i = 1 ;i <= n ;i ++)
       {
          if(mid >= node[i].A)
          {
             sum += ((minn(mid ,node[i].B) - node[i].A) / node[i].C + 1);
          }
       }
       return sum;
    }
          
    
    int main ()
    {
       int n ,i;
       __int64 INF = 1;
       for(__int64 ii = 1 ;ii <= 31 ;ii ++)
       INF *= 2;
       while(~scanf("%d" ,&n))
       {
          for(i = 1 ;i <= n ;i ++)
          scanf("%I64d %I64d %I64d" ,&node[i].A ,&node[i].B ,&node[i].C);  
          __int64 tmp = solve(INF ,n);
          if(tmp % 2 == 0)
          {
             puts("DC Qiang is unhappy.");
             continue;
          }  
          __int64 low ,up ,mid;
          low = 0 ,up = INF;
          __int64 ans_id = -1;
          while(low <= up)
          {
             mid = (low + up) / 2;
             tmp = solve(mid ,n);
             //printf("%I64d******
    " ,tmp);
             if(tmp % 2)
             {
                up = mid -  1;
                ans_id = mid;
             }
             else 
             {
               low = mid + 1;
             }
          }
          __int64 ans_sum = 0;
          for(i = 1 ;i <= n ;i ++)
          {
             if(ans_id <= node[i].B && (ans_id - node[i].A) % node[i].C == 0 && ans_id >= node[i].A)
             ans_sum ++;
          }
          printf("%I64d %I64d
    " ,ans_id ,ans_sum);
       }
       return 0;
    }
    



  • 相关阅读:
    VC 常见问题百问
    python windows 环境变量
    Check server headers and verify HTTP Status Codes
    Where are the AES 256bit cipher suites? Please someone help
    outlook 如何预订会议和会议室
    安装Axis2的eclipse插件后,未出现界面
    windows 环境变量
    python 时间日期处理汇集
    openldap学习笔记(使用openldap2.3.32)
    set p4 environment in windows
  • 原文地址:https://www.cnblogs.com/csnd/p/12063127.html
Copyright © 2011-2022 走看看