zoukankan      html  css  js  c++  java
  • 2020 CCPC-Wannafly Winter Camp Day7 ---A.序列

    对于每个元素对(i,j),对于所有min((s_i),(s_j))<x<max((s_i),(s_j)),这个元素对的贡献都是(2^{n-(j-i+1)})
    (2^{i-j})
    我们考虑k+1的得分和,就是k的得分和减去一部分,再加上一部分。
    减去的一部分只对k有贡献而对k+1没有贡献的,是(1,k+1),(2,k+1)...(k-1,k+1)这些值对应的位置对的贡献
    加上的一部分只对k+1有贡献而对k没有贡献的,是(k,k+2),(k,k+3)..(k,n)这些值对应的位置对的贡献
    于是我们求出所有(delta_k)=(ans_k)-(ans_{k-1})
    1.我们从前往后扫描序列,对于当前位置我们考虑它作为位置对的右端点,即上述j。
    那么我们认为这个点的贡献是(2^{n-j})
    我们将这个点作为值对的右端点,即大的那一个,那我们求出j位置前面所有小于(s_j)的数作为位置对的左端点,贡献为(2^{i-1})。这会对(delta_{s_j})产生-(sum 2^{i-1})的贡献。
    我们将这个点作为值对的左端点,即小的哪一个,那我们求处j位置前面所有大于(s_j)的数作为位置对的左端点,贡献为(2^{i-1})。这会对(delta_{s_{j+1}})产生(sum 2^{i-1})的贡献。
    所有符合条件的(2^{i-1})的和我们用树状数组维护即可。
    每次将计算完答案,将这个点作为左端点塞进树状数组。
    2.我们再从后往前扫描序列,对于当前位置我们考虑作为位置对的左端点,及上述i。
    做法同上。

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    
    const ll mol = 1e9 +7;
    const int maxn = 1e5;
    int n;
    int a[maxn + 11];
    ll delta[maxn + 11],mul[maxn + 11],bit[maxn + 11];
    
    ll sub(ll a,ll b) { a -= b; return a < 0 ? a + mol : a; }
    ll add(ll a,ll b) { a += b; return a >= mol ? a - mol : a; }
    int lowbit(int x) { return x & (-x); }
    void upd(int x,ll val) { for (; x <= n; x += lowbit(x)) bit[x] = add(bit[x] , val); }
    ll query(int x) { ll ans = 0; for (; x ; x -= lowbit(x)) ans = add(ans , bit[x]); return ans; }
    
    int main(){
        scanf("%d" , &n);
        for (int i = 1; i <= n; i++) scanf("%d" , &a[i]);
        mul[0] = 1;
        for (int i = 1; i <= n; i++) mul[i] = mul[i - 1] * 2 % mol;
        for (int i = 1; i <= n; i++) {
            ll val = query(a[i] - 1) * mul[n - i] % mol;
            delta[a[i]] = sub(delta[a[i]] , val);
            val  = sub(query(n) , query(a[i])) * mul[n - i] % mol;
            delta[a[i] + 1] = add(delta[a[i] + 1] , val);
            upd(a[i] , mul[i - 1]);
        }
        for (int i = 1; i <= n; i++) bit[i] = 0;
        for (int i = n; i >= 1; i--) {
            ll val = sub(query(n) , query(a[i])) * mul[i - 1] % mol;
            delta[a[i] + 1] = add(delta[a[i] + 1] , val);
            val = query(a[i] - 1) * mul[i - 1] % mol;
            delta[a[i]] = sub(delta[a[i]] , val);
            upd(a[i] , mul[n - i]);
        }
        for (int i = 1; i <= n; i++) {
            delta[i] = add(delta[i] , delta[i - 1]);
            printf("%lld
    " , delta[i]);
        }
    }
    
  • 相关阅读:
    java----session
    js封装成插件-------Canvas统计图插件编写
    js封装成插件
    js学习--变量作用域和作用域链
    学习js函数--自执行函数
    学习js函数--函数定义
    footer不满一屏时在最底部,超出一屏时在页面最下部
    ios 点击区域阴影问题
    提交表单后数据返回时间过长
    点击显示video
  • 原文地址:https://www.cnblogs.com/Embiid/p/12260295.html
Copyright © 2011-2022 走看看