zoukankan      html  css  js  c++  java
  • 2020 CCPC Wannafly Winter Camp Day7 A(求任何子序列中相邻范围内数的个数的总和)

    题:https://ac.nowcoder.com/acm/contest/4138/A

    题意:给定一个1~n的序列,在任意长度大于等于2的子序列中,假设相邻的为x,y,那么若min(x,y)<=k<=max(x,y),那么询问的k增加1的贡献,问k为1~n的答案为多少

    分析:考虑每个i 和 j (i<j)对k的贡献,假设对k有贡献,那么合法的区间有2i-1 * 2n-j

       即对k而言,考虑[1,k-1] 和 [k+1,n]的匹配对数;

       假设我们已经算出k,那么对于k+1,即考虑[1,k] 和 [k+2,n];

       我们发现实际上就从k那里加上 [k] 和 [k+2,n]的贡献,减去 [1,k-1] 和 [k+1] 的贡献;

       用树状数组处理差分数组b[]即可,最后将数组反转一遍再做相同处理即可;

    #include<bits/stdc++.h>
    using namespace std;
    const int mod=1e9+7;
    const int M=1e5+5;
    typedef long long ll;
    int a[M],n;
    ll b[M],mi[M];
    struct BIT{
        ll tr[M+5];
        void init(){ memset(tr,0,sizeof(tr)); }
        void add(int x,ll c){
            for(int i=x;i<M;i+=i&-i) tr[i]=(tr[i]+c)%mod;
        }
        ll sum(int x){
            ll res=0;
            for(int i=x;i;i-=i&-i) res=(res+tr[i])%mod;
            return res;
        }
    }bit;
    void solve(){
        bit.init();
        for(int i=n;i>=1;i--){
            ll val=(bit.sum(n)-bit.sum(a[i]+1)+mod)%mod;///[a[i]+2,n]作为右端点
            val=val*mi[i-1]%mod;
            b[a[i]+1]=(b[a[i]+1]+val)%mod;
            bit.add(a[i],mi[n-i]);
        }
        bit.init();
        for(int i=1;i<=n;i++){
            if(a[i]>2){
                ll val=bit.sum(a[i]-2);///上面处理的是a[i]+1,所以减去的部分要对应上a[i]+1,因此要减去2
                val=val*mi[n-i]%mod;
                b[a[i]]=(b[a[i]]-val+mod)%mod;
    
            }
            bit.add(a[i],mi[i-1]);
        }
    }
    int main(){
        mi[0]=1;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) mi[i]=mi[i-1]*2ll%mod;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        solve();
        reverse(a+1,a+1+n);
        solve();
        ll ans=0;
        for(int i=1;i<=n;i++){
            ans=(ans+b[i])%mod;
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    c语言 作用域、存储期、链接属性汇总
    进程上下文切换分析
    进程装载过程分析(execve系统调用分析)
    fork 创建进程的过程分析
    系统调用软中断处理程序system_call分析
    linux 系统调用分析
    8分钟带你深入浅出搞懂Nginx
    控制反转
    JAVA泛型(转)
    AOP(转)
  • 原文地址:https://www.cnblogs.com/starve/p/13855132.html
Copyright © 2011-2022 走看看