• 【题解】我也不是B ifrog 1112 二分 倍增


    题目传送门:http://ifrog.cc/acm/problem/1112

    神奇的倍增二分,长见识了,在此做个记录,分享给大家。

    懒得写题解了,直接转YJQ的:http://ifrog.cc/acm/solution/18

    另外,这个复杂度的证明我不是很懂,只会自己瞎脑补的不严谨的证明,如果哪位神犇会,还请教教我qwq。

    代码:

     1 #include <cstring>
     2 #include <algorithm>
     3 #include <cstdio>
     4 
     5 using namespace std;
     6 typedef long long ll;
     7 const int MAXN = 300010;
     8 
     9 int n;
    10 ll m, a[MAXN], v[MAXN];
    11 int ans[MAXN] = {0};
    12 
    13 ll tmp[MAXN];
    14 bool check( int begin, int end ) { // 区间混乱度大于m返回true
    15     for( int i = begin; i < end; ++i ) tmp[i] = a[i];
    16     sort(tmp+begin, tmp+end);
    17     ll sum = 0;
    18     for( int i = begin; i < end; ++i )
    19         sum += tmp[i] * v[i-begin];
    20     return sum > m;
    21 }
    22 
    23 int main() {
    24     scanf( "%d%lld", &n, &m );
    25     for( int i = 0; i < n; ++i ) scanf( "%lld", a+i );
    26     for( int i = 0; i < n; ++i ) scanf( "%lld", v+i );
    27     for( int i = 0; i < n; ) {
    28         int k;
    29         for( k = 1; i+k <= n; k <<= 1 ) // 倍增,左闭右开区间
    30             if( check(i,i+k) ) break;
    31         k = min(k, n-i);
    32         int low = i+(k>>1), high = i+k;
    33         while( low < high ) { // 二分
    34             int mid = (low+high)>>1;
    35             if( check(i,mid) ) high = mid;
    36             else low = mid+1;
    37         }
    38         if( check(i,low) ) ans[low-1] = 1;
    39         i = low;
    40         // printf( "low = %d
    ", low );
    41     }
    42     for( int i = 0; i < n; ++i ) {
    43         if(i) ans[i] += ans[i-1], putchar(' ');
    44         printf( "%d", ans[i] );
    45     }
    46     puts("");
    47     return 0;
    48 }
  • 相关阅读:
    Oracle配置手册
    Vim配置手册
    高斯消元
    dp专场的蒟蒻题解
    mac 软件意外退出
    spring security整体流程
    服务启动shell脚本
    nohup 启动命令
    linux service脚本
    docker 安装prometheus和grafna
  • 原文地址:https://www.cnblogs.com/mlystdcall/p/6656871.html
Copyright © 2020-2023  润新知