hdu5439 二分

题意

初始给了 1 2 两个数

第二步 因为第2个数是2 所以  在序列后面放上2个2 包括他自己之前有的 序列变成 1 2 2

第三步 因为第3个数是2 所以  在序列后面放上2个3 就变成了 1 2  2 3 3

第4步   第4个数为3    所以 在序列后面放上3个4   变成 1 2 2 3 3 4 4 4

以此类推  序列就是  1 2 2 3 3 4 4 4 5 5 5 6 6 6 6 7 7 7 7 8 8 8 8。。。

求的是n的最后出现位置 的最后出现位置, 也就是说 如果 n最后一次出现在第k位 那么 k的最后一次出现在哪里

我们可以知道 如果答案询问的是n 那么我们就可以知道 回答的肯定是  n最后所在的位置的前K项和,可想而知 !!!比如查询 3 那么就是求前5项的和

但是好像100000000那么多不太如意

在分解

1*1+(2+3)*2 这个答案是3的答案

那么 10呢?

就是 1*1+(2+3)*2+(4+5)*3+(6+7+8)*4+(9+10)*5;

好像知道了 最后要计算的就是 括号里面最大的那个值得为止的上式的和 那么但是我并不知道 后面乘的那个k得有多大 可以使得括号里面的最大值为1000000000,打了一下表发现 500000足够了

于是 用二分 +求和了

#include <iostream>
#include <algorithm>
#include <string.h>
#include <cstdio>
using namespace std;
typedef long long LL;
const int maxn=500005;
const LL MOD=1000000007;
struct elem{
  LL L,R;
  elem(LL cL=0,LL cR=0)
  {
    L=cL; R=cR;
  }
}P[maxn];
int cnt;
LL sum[maxn];
int look(LL d)
{
     int L=1,R=cnt-1;
     int ans=0;
     while(L<=R){
         int mid=(L+R)>>1;
         if(P[mid].L<=d&&P[mid].R>=d){
            ans=mid;break;
         }
         if(P[mid].L>d){
            R=mid-1;
         }else{
            L=mid+1;
         }
     }
     return ans;
}
void init()
{
    cnt=1;
   P[cnt++]=elem(1,1);
   P[cnt++]=elem(2,3);
   LL loc=4;
   for(int i=3; i<=500000; i++)
    {
       int d=look(i);
       P[cnt++]=elem(loc,loc+d-1);
       loc=loc+d;
    }
    sum[0]=0;
    for(LL i=1 ; i<cnt; i++)
        {
             LL nu=P[i].R-P[i].L+1;
             LL s= (P[i].L+P[i].R)*nu/2;
             s=(s*i)%MOD;
             sum[i]=(s+sum[i-1])%MOD;
        }
}
int main()
{
    init();
    int cas;
    scanf("%d",&cas);
    for(int cc=1; cc<=cas; cc++)
    {
        LL loc;
        scanf("%I64d",&loc);
        LL d=look(loc);
        LL ans=sum[d-1];
        LL s=1LL*(loc-P[d].L+1)*(loc+P[d].L)/2;
        s=((s%MOD)*d)%MOD;
        ans=(ans+s)%MOD;
        printf("%I64d\n",ans);
    }
    return 0;
}
时间: 2024-10-14 05:27:16

hdu5439 二分的相关文章

2.1 二分分类

本周学习神经网络编程的基础知识 构建神经网络,有些技巧是非常重要 神经网络的计算过程中,通常有一个正向的过程(正向传播步骤),接着会有一个反向步骤(反向传播步骤), 为什么神经网络的计算可以分为前向传播和反向传播两个分开的过程?本周课程通过使用logistic回归来阐述,以便于能够更好的理解, logistic回归是一个用于二分分类的算法 比如有一个二分分类问题的例子, 假如有一张图像作为输入是这样的,你想输出识别此图的标签,如果是猫,输出1,如果不是,则输出0 使用y来表示输出的结果标签, 来

HDU3715(二分+2-SAT)

Go Deeper Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 3184    Accepted Submission(s): 1035 Problem Description Here is a procedure's pseudocode: go(int dep, int n, int m)beginoutput the valu

二分查找

递归版(在区间[x, y)中找v的位置) 1 //递归版二分查找 2 int bsearch(int * A, int x, int y, int v) 3 { 4 5 if(v<a[x] || v>a[y-1]) return -1; 6 int m = x + (y-x)/2; //此处能不能用int m = (x+y)/2,需要仔细考虑(暂时想不到原因) 7 if(A[m]==v) return m; 8 else if(A[m]>v) return bsearch(A, x, m

Codeforces 772A Voltage Keepsake - 二分答案

You have n devices that you want to use simultaneously. The i-th device uses ai units of power per second. This usage is continuous. That is, in λ seconds, the device will use λ·ai units of power. The i-th device currently has bi units of power store

二分查找总结

最近刷leetcode和lintcode,做到二分查找的部分,发现其实这种类型的题目很有规律,题目大致的分为以下几类: 1.最基础的二分查找题目,在一个有序的数组当中查找某个数,如果找到,则返回这个数在数组中的下标,如果没有找到就返回-1或者是它将会被按顺序插入的位置.这种题目继续进阶一下就是在有序数组中查找元素的上下限.继续做可以求两个区间的交集. 2.旋转数组问题,就是将一个有序数组进行旋转,然后在数组中查找某个值,其中分为数组中有重复元素和没有重复元素两种情况. 3.在杨氏矩阵中利用二分查

BZOJ 1044 木棍分割 解题报告(二分+DP)

来到机房刷了一道水(bian’tai)题.题目思想非常简单易懂(我的做法实际上参考了Evensgn 范学长,在此多谢范学长了) 题目摆上: 1044: [HAOI2008]木棍分割 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3162  Solved: 1182[Submit][Status][Discuss] Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个

hdu_5884_Sort(二分+单调队列)

题目链接:hdu_5884_Sort 题意: 有n个数,每个数有个值,现在你可以选择每次K个数合并,合并的消耗为这K个数的权值和,问在合并为只有1个数的时候,总消耗不超过T的情况下,最小的K是多少 题解: 首先要选满足条件的最小K,肯定会想到二分. 然后是如何来写这个check函数的问题 我们要贪心做到使消耗最小,首先我们将所有的数排序 然后对于每次的check的mid都取最小的mid个数来合并,然后把新产生的数扔进优先队列,直到最后只剩一个数. 不过这样的做法是n*(logn)2 ,常数写的小

BZOJ_1014_[JSOI2008]_火星人prefix_(Splay+LCP_Hash+二分)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1014 给出一个字符串,有修改,插入,以及询问LCP(i,j)的操作. 分析 LCP在白书上面有介绍,\(LCP(i,j)\)表示以第\(i\)位和以第\(j\)位开头的后缀的最长公共前缀. 先考虑没有插入和修改操作的问题.我们可以用基于Hash的LCP算法. 我们给每一个后缀一个Hash值.其中以第\(i\)为开头的后缀的Hash值为\(H[i]=H[i+1]x+s[i]\). 其中\(x\

HDU 2141 Can you find it? 二分查找

Can you find it? Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/10000 K (Java/Others)Total Submission(s): 21485    Accepted Submission(s): 5446 Problem Description Give you three sequences of numbers A, B, C, then we give you a number