zoukankan      html  css  js  c++  java
  • 51Nod 1680 区间求和 树状数组

    题意:

    给出一个长度为(n)的数列(A_i),定义(f(k))为所有长度大于等于(k)的子区间中前(k)大数之和的和。
    (sum_{k=1}^{n}f(k) ; mod ; 10^9+7)

    分析:

    从某个长度为(k)的子区间对答案的贡献来看:
    它的长度大于等于(k),所以区间中每个都加到答案中一次。
    它的长度还大于等于(k-1),区间中前(k-1)大的数加到答案中一次。
    ……
    以此类推。

    对于每个数(A_i):如果这个区间中有(x)个小于(A_i)的数,这个数对答案就会贡献(x+1)次。

    所以如果存在(A_i<A_j,i<j),包含这两个数区间的个数为(i imes (n - j + 1))
    对答案的贡献为(A_j cdot i cdot (n - j + 1))
    (A_i<A_j,i>j)的情况类似,所以可以枚举(A_j),求和用一个树状数组维护。

    • 对于数字相等的情况还是要区分开来的,可以用它们的下标再比较一次大小,这样做到了不重不漏。
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <set>
    #include <vector>
    #include <iostream>
    #include <string>
    using namespace std;
    #define REP(i, a, b) for(int i = a; i < b; i++)
    #define PER(i, a, b) for(int i = b - 1; i >= a; i--)
    #define SZ(a) ((int)a.size())
    #define MP make_pair
    #define PB push_back
    #define EB emplace_back
    #define ALL(a) a.begin(), a.end()
    #define F first
    #define S second
    #define lowbit(x) (x&(-x))
    typedef long long LL;
    typedef pair<LL, int> PII;
    
    const int maxn = 1000000 + 10;
    const LL MOD = 1000000007LL;
    
    LL mul(LL a, LL b) { return a * b % MOD; }
    void add(LL& a, LL b) { a += b; if(a >= MOD) a -= MOD; }
    
    int n;
    LL A, B, C;
    LL a[maxn];
    PII b[maxn];
    
    LL bit[maxn];
    void init() { memset(bit, 0, sizeof(bit)); }
    void update(int x, int v) {
    	while(x <= n) {
    		add(bit[x], v);
    		x += lowbit(x);
    	}
    }
    int query(int x) {
    	LL ans = 0;
    	while(x) {
    		add(ans, bit[x]);
    		x -= lowbit(x);
    	}
    	return ans;
    }
    
    int main() {
    	scanf("%d%lld%lld%lld%lld", &n, &a[1], &A, &B, &C);
    	A %= C; B %= C;
    	b[1].F = a[1];
    	b[1].S = 1;
    	REP(i, 2, n + 1) {
    		a[i] = ((a[i - 1] * A) % C) + B;
    		if(a[i] >= C) a[i] -= C;
    		b[i].F = a[i];
    		b[i].S = i;
    	}
    	sort(b + 1, b + 1 + n);
    	REP(i, 1, n + 1)
    		a[i] = lower_bound(b + 1, b + 1 + n, MP(a[i], i)) - b;
    
    	LL ans = 0;
    	REP(i, 1, n + 1) {
    		update(a[i], i);
    		LL t = mul(b[a[i]].F, (LL)(n - i + 1));
    		add(ans, mul(query(a[i]), t));
    	}
    	init();
    	PER(i, 1, n + 1) {
    		LL t = mul(b[a[i]].F, (LL)i);
    		add(ans, mul(query(a[i]), t));
    		update(a[i], n - i + 1);
    	}
    	printf("%lld
    ", ans);
    
    	return 0;
    }
    
  • 相关阅读:
    HelloCSS-Border
    开发你的第一个NCS(Zephyr)应用程序
    NanoPi R4S (RK3399) openssl speed 硬件加解密性能测试结果
    Flink-状态
    Flink-时间语义和Watermark
    Flink-Window
    Flink-运行时架构
    Flink-流处理wordcount
    Flink-批处理wordcount
    设计模式七大原则-合成复用原则
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/6945740.html
Copyright © 2011-2022 走看看