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]);
        }
    }
    
  • 相关阅读:
    Ubuntu上安装Redis
    Unity Shader中将指定颜色过滤成透明
    用Python发送邮件
    Flask搭建简单的服务器
    SQLServer 中All、Any和Some用法与区别
    Linux探秘之用户态与内核态
    MTDDL 美团点评分布式数据访问层中间件
    基础数据结构 例:栈、队列、链表、数据、字典、树、等
    二叉树、红黑树、B&B+树数据结构
    CPU,GPU,高速缓存cache,内存RAM,虚拟内存VM,磁盘ROM,磁盘缓存之间的关系
  • 原文地址:https://www.cnblogs.com/Embiid/p/12260295.html
Copyright © 2011-2022 走看看