zoukankan      html  css  js  c++  java
  • HDU

    HDU - 5358

    首先把公式拆开来, i,j 的贡献分开算。

    从一个点开始的值只有LOG个。

    一个很直观的思路就是二分出所有的分界点, 然后T了。

    考虑优化就是从1 扫到 n的时候用35个指针去维护分界点, 因为是单调的所以是n * logn的复杂度。

    不过这个题好像有点卡常。

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize(4)
    #include<bits/stdc++.h>
    #define LL long long
    #define LD long double
    #define ull unsigned long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ALL(x) (x).begin(), (x).end()
    #define fio ios::sync_with_stdio(false); cin.tie(0);
    
    using namespace std;
    
    const int N = 1e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    const double PI = acos(-1);
    
    template<class T, class S> inline void add(T &a, S b) {a += b; if(a >= mod) a -= mod;}
    template<class T, class S> inline void sub(T &a, S b) {a -= b; if(a < 0) a += mod;}
    template<class T, class S> inline bool chkmax(T &a, S b) {return a < b ? a = b, true : false;}
    template<class T, class S> inline bool chkmin(T &a, S b) {return a > b ? a = b, true : false;}
    
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    
    const int LOG = 35;
    
    int n;
    int a[N];
    LL bin[N], sum[N];
    
    int pt[35];
    
    int main() {
        for(int i = 0; i < LOG + 5; i++) {
            bin[i] = 1LL << i;
        }
        int T; scanf("%d", &T);
        while(T--) {
            scanf("%d", &n);
            for(int i = 1; i <= n; i++) {
                scanf("%d", &a[i]);
                sum[i] = sum[i - 1] + a[i];
            }
    
            LL ans = 0;
    
            for(int i = 0; i < 35; i++) {
                pt[i] = 0;
            }
            for(int i = 1; i <= n; i++) {
                pt[0] = i - 1;
                for(int j = 1; j < 35; j++) {
                    while(pt[j] < n && sum[pt[j] + 1] - sum[i - 1] < bin[j]) pt[j]++;
                }
                for(int j = 1; j < 35; j++) {
                    ans += 1LL * (pt[j] - pt[j - 1]) * j * i;
                }
            }
    
            for(int i = 0; i < 35; i++) {
                pt[i] = n + 1;
            }
    
            for(int i = n; i >= 1; i--) {
                pt[0] = i + 1;
                for(int j = 1; j < 35; j++) {
                    while(pt[j] > 1 && sum[i] - sum[pt[j] - 2] < bin[j]) pt[j]--;
                }
                for(int j = 1; j < 35; j++) {
                    ans += 1LL * (pt[j - 1] - pt[j]) * j * i;
                }
            }
    
            printf("%lld
    ", ans);
        }
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    Leetcode Reverse Words in a String
    topcoder SRM 619 DIV2 GoodCompanyDivTwo
    topcoder SRM 618 DIV2 MovingRooksDiv2
    topcoder SRM 618 DIV2 WritingWords
    topcoder SRM 618 DIV2 LongWordsDiv2
    Zepto Code Rush 2014 A. Feed with Candy
    Zepto Code Rush 2014 B
    Codeforces Round #245 (Div. 2) B
    Codeforces Round #245 (Div. 2) A
    Codeforces Round #247 (Div. 2) B
  • 原文地址:https://www.cnblogs.com/CJLHY/p/11201120.html
Copyright © 2011-2022 走看看