zoukankan      html  css  js  c++  java
  • 二分-hdu-4768-Flyer

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=4768

    题目意思:

    有n个A、B、C,每个Ai,Bi,Ci,对于每个P=Ai+k*Ci(P<=Bi,k为整数) 标记一次,如果存在,数据保证只有一个数被标记了奇数次,求出那个数并输出次数。

    解题思路:

    二分答案。统计区间内所有数的出现次数,根据奇数+偶数=奇数原则。只有一个数是奇数,来决定移动的方向。

    最大的n可能有2^31,暴力肯定不行,但网赛的时候很多人都是抑或o(2^31)*n过得,无语了。

    二分要求的那个数,对于0~mid段,如果该区间内所有数一共出现了奇数次,则只可能在前面一段,如果是偶数,则肯定在后面一段。每次只用求0~mid该区间所有的值得出现次数和即可,因为奇数减偶数,奇偶性不变。所以每次只用求一遍,然后对于每个mid值,特判一下该点是否为要求的点,如果是的话就找到了。

    注意用__int64.

    代码:

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<sstream>
    #include<cstdlib>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<stack>
    #include<list>
    #include<queue>
    #include<ctime>
    #include<bitset>
    #define eps 1e-6
    #define INF 0x3f3f3f3f
    #define PI acos(-1.0)
    #define ll __int64
    #define LL long long
    #define lson l,m,(rt<<1)
    #define rson m+1,r,(rt<<1)|1
    #pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    
    #define Maxn 21000
    
    ll A[Maxn],B[Maxn],C[Maxn],n;
    
    ll iscan(ll m,ll &sum)//sum是区间0~m中所有数出现次数的总和
    {
        ll res=0;  //res表示数m出现的次数
        sum=0;
        for(int i=1;i<=n;i++)
        {
            ll tmp=min(B[i],m);
            if(tmp>=A[i])
                sum+=(tmp-A[i])/C[i]+1;
            if(m>B[i]||m<A[i]) //都不行 注意 m<A[i]
                continue;
            if((m-A[i])%C[i]==0) //注意m是一个数
                res++;
        }
        return res;
    }
    
    int main()
    {
    
        while(~scanf("%I64d",&n))
        {
            ll Max=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%I64d%I64d%I64d",&A[i],&B[i],&C[i]);
                Max=max(Max,B[i]);
            }
            ll l=0,r=Max,mid;
            ll ans=-1,aa;
    
            while(l<=r)
            {
                mid=(l+r)>>1;
                //printf("%I64d,%I64d %I64d
    ",l,r,mid);
                ll tmp=0;
                aa=iscan(mid,tmp);
                //printf("%I64d %I64d
    ",aa,tmp);
                //system("pause");
                if(aa&1) //mid这个数符不符合
                {
                    ans=mid;
                    break;
                }
                if(tmp&1) //前一段区间为存在某数为奇数个
                    r=mid-1;
                else
                    l=mid+1;
            }
            if(ans==-1)
            {
                printf("DC Qiang is unhappy.
    ");
            }
            else
                printf("%I64d %I64d
    ",ans,aa);
        }
       return 0;
    }
    


  • 相关阅读:
    sharepoint ECMA 添加指定的人员和指定的角色到某个list里
    sharepoint ECMA 添加User到Site组
    sharepoint ECMA PeopleEditor 清除选中的中的人员
    sharepoinT Modal Dialog
    sharepoint ECMA
    sharepoint 列表查询范围
    sharepoint 2013 添加Quickpart
    背包、队列和栈
    Java 同步块
    Andriod性能优化笔记
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3348072.html
Copyright © 2011-2022 走看看