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;
    }
    
    /*
    */
  • 相关阅读:
    164 Maximum Gap 最大间距
    162 Find Peak Element 寻找峰值
    160 Intersection of Two Linked Lists 相交链表
    155 Min Stack 最小栈
    154 Find Minimum in Rotated Sorted Array II
    153 Find Minimum in Rotated Sorted Array 旋转数组的最小值
    152 Maximum Product Subarray 乘积最大子序列
    151 Reverse Words in a String 翻转字符串里的单词
    bzoj3994: [SDOI2015]约数个数和
    bzoj 4590: [Shoi2015]自动刷题机
  • 原文地址:https://www.cnblogs.com/CJLHY/p/11201120.html
Copyright © 2011-2022 走看看