• hdu5338 (二进制,双指针)


    这种双循环的优化问题碰到过很多了。层出不穷。 但无非就是要利用前面循环时,所产生的信息,从而减少计算。

    可以注意到log其实是不超过40的, 那么以这方面入手,时间复杂度就可以降为nlogn

    log=4的区间肯定是log=1的区间加元素而来的,肯定是log=2的区间加元素而来的,肯定是log=3的区间加元素而来的,肯定是log=4的区间增加元素而来的。

    可以发现刚好有4个区间可以变为log=4

    所以每次计算log1,log2,log3,log4的时候, 后面的区间肯定是包含它们的

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdlib.h>
     4 #include <algorithm>
     5 #include <iostream>
     6 #include <queue>
     7 #include <stack>
     8 #include <vector>
     9 #include <map>
    10 #include <set>
    11 #include <string>
    12 #include <math.h>
    13 using namespace std;
    14 #pragma warning(disable:4996)
    15 #pragma comment(linker, "/STACK:1024000000,1024000000")
    16 typedef long long LL;                   
    17 const int INF = 1<<30;
    18 /*
    19 
    20 */
    21 const int N = 100000 + 10;
    22 int a[N];
    23 LL sum[N];
    24 
    25 int main()
    26 {
    27     
    28     int t, n;
    29     scanf("%d", &t);
    30     LL ans;
    31     while (t--)
    32     {
    33         ans = 0;
    34         scanf("%d", &n);
    35         sum[n + 1] = 0;
    36         for (int i = 1; i <= n; ++i)scanf("%d", &a[i]);
    37         for (int i = n; i >= 1; --i)
    38         {
    39             sum[i] = sum[i + 1] + i;
    40             //计算所有的1*(i+j), 因为log取整之后有+1
    41             ans += (LL)(n - i + 1)*i + sum[i];
    42         }
    43         
    44         for (int k = 1; k < 40; ++k)
    45         {
    46             LL lim = 1LL << k;
    47             LL s = 0;
    48             for (int i = 1, j = 1; i <= n; ++i)
    49             {
    50                 while (j <= n &&s < lim)
    51                     s += a[j++];
    52                 if (s >= lim)//[i,j-1->n]的区间肯定是大于等于lim的
    53                     ans += (LL)(n- j + 2) * i + sum[j - 1];
    54                 else
    55                     break;
    56                 s -= a[i];
    57             }
    58         }
    59         printf("%lld
    ", ans);
    60     }
    61     return 0;
    62 }
    View Code
  • 相关阅读:
    cocos2d-x类型转换(CCstring int string char UTF-8互转)
    cocos2d-x 实心圆
    CCLabelTTF的多行显示(仅限中文)
    cocos2d-x 弹窗
    cocos2d-x 画线
    cocos2d-x 利用CCLabelTTF制作文字描边与阴影效果的实现方法
    cocos2d-x 背景色修改
    cocos2d-x 中文乱码问题
    HelloWorld.exe 中的 0x0f9265f6 (libcocos2d.dll) 处有未经处理的异常: 0xC0000005: 读取位置 0x00000038 时发生访问冲突
    error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4710003.html
Copyright © 2020-2023  润新知