树状数组维护前缀和、后缀和、个数|牛牛的Link Power

思路

另线段树做法:https://www.cnblogs.com/fisherss/p/12287606.html

F题树状数组维护前缀即可

题目地址

https://ac.nowcoder.com/acm/contest/3004/F

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 1e5+100;
int n;
char s[maxn];
const ll mod = 1e9+7;

struct bit{
	ll c[maxn];

	int lowbit(int x){
		return x & -x;
	}

	void add(int pos,int v){
		while(pos <= n){
			c[pos] += v;
			pos += lowbit(pos);
		}
	}

	ll getsum(int pos){
		ll res = 0;
		while(pos){
			res += c[pos];
			pos -= lowbit(pos);
		}
		return res;
	}

}pre,suf,cnt;

int main(){
	cin>>n;
	scanf("%s",s+1);
	ll ans = 0;
	for(int i=1;i<=n;i++){
		if(s[i] == ‘1‘){
			cnt.add(i,1);
			pre.add(i,i);
			ans = (ans + i*cnt.getsum(i) - pre.getsum(i))%mod;
		}
	}
	cout<<ans<<endl;
	return 0;
}

G题 3棵树状数组维护前缀和、后缀和、个数

题目地址

https://ac.nowcoder.com/acm/contest/3004/G

70%,wa

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 1e5+100;
ll n;
char s[maxn];
const ll mod = 1e9+7;

struct bit{
	ll c[maxn];

	ll lowbit(ll x){
		return x & -x;
	}

	void add(ll pos,ll v){
		while(pos <= n){
			c[pos] += v;
			pos += lowbit(pos);
		}
	}

	ll getsum(ll pos){
		ll res = 0;
		while(pos){
			res += c[pos];
			pos -= lowbit(pos);
		}
		return res;
	}

}pre,suf,cnt;

void print(){
	for(int i=1;i<=n;i++){
		cout<<suf.getsum(i)<<" ";
	}
	cout<<endl;
}

int main(){
	cin>>n;
	scanf("%s",s+1);
	ll ans = 0;
	for(ll i=1;i<=n;i++){
		if(s[i] == ‘1‘){
			cnt.add(i,1);
			pre.add(i,i);
			suf.add(i,n-i+1);
			ans = (ans + i*cnt.getsum(i) - pre.getsum(i))%mod;
		}
	}
	cout<<ans%mod<<endl;
	ll m;
	cin>>m;
	while(m--){
		ll q,pos;
		cin>>q>>pos;
		if(q == 1){
			//加点
			cnt.add(pos,1);
			pre.add(pos,pos);
			suf.add(pos,n-pos+1);
			//加上对前缀1的贡献影响
			ans = (ans + (pos*cnt.getsum(pos) - pre.getsum(pos)))%mod;
			//加上对后缀1的贡献影响
			ans = (ans + ((n - pos + 1) * (cnt.getsum(n) - cnt.getsum(pos-1)) - (suf.getsum(n) - suf.getsum(pos-1))))%mod;
		}else{
			ans = (ans - (pos*cnt.getsum(pos) - pre.getsum(pos)))%mod;
			ans = (ans - ((n - pos + 1) * (cnt.getsum(n) - cnt.getsum(pos-1)) - (suf.getsum(n) - suf.getsum(pos-1))))%mod;
			cnt.add(pos,-1);
			pre.add(pos,-pos);
			suf.add(pos,-(n-pos+1));
		}
		cout<<ans%mod<<endl;
	}
	return 0;
}

原文地址:https://www.cnblogs.com/fisherss/p/12657814.html

时间: 2024-10-14 14:02:35

树状数组维护前缀和、后缀和、个数|牛牛的Link Power的相关文章

树状数组维护前缀和

树状数组是用来维护序列前缀和的数据结构.它的修改与求和都是O(logn)的,效率非常高. 我们设序列为A,则树状数组c中,c[i]记录序列A的区间[ i-lowbit(i)+1 , i ]中所有数的和. (树状数组是个好东西ovo)  树状数组在进行区间操作时,要从上到下访问,进行单点操作时,要从下到上访问.  树状数组维护序列前缀和的模版如下: #include <iostream> #include <cstdio> #define maxn 500005 using name

Codeforces Round #629 (Div. 3) F - Make k Equal (离散化 树状数组维护前缀和)

https://codeforces.com/contest/1328/problem/F 首先把a数组处理成pair对(num,cnt),表示数字num有cnt个,然后按num升序排序离散化一下. 对于一个数x,若想使得小于x的数字都变成x,必须先把所有小于x的数变成x-1,然后再+1变成x. 同理,要使得大于x的数变成x,必须把所有大于x的数字变成x+1,然后再-1变成x. 以上是题意所要求的必须操作. 思路: 1. 用f[i]数组记录离散化后前i大的数字的总数,那么对于任意第i大数字,可以

51Nod 1272最大距离 (树状数组维护前缀最小值)

题目链接 最大距离 其实主流解法应该是单调栈--我用了树状数组. 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define rep(i, a, b) for (int i(a); i <= (b); ++i) 6 7 const int N = 100010; 8 9 struct node{ 10 int x, y; 11 friend bool operator < (const node &a, c

ACdreamoj 1011(树状数组维护字符串hash前缀和)

题目链接:http://acdream.info/problem? pid=1019 题意:两种操作,第一种将字符串某个位置的字符换为还有一个字符.另外一种查询某个连续子序列是否是回文串: 解法:有两种hash的办法,所以写了两种解法;首先hash是x1 * p^1+ x2*p^2 +x3*p^3...能够用树状数组维护前缀和,维护两个串,一个是正串.还有一个是反串用于比較.比較时候乘以对应的p倍数推断是否相等. 刘汝佳白书上的hash方法处理这道题更复杂:改动i会对后缀j产生的影响为a*p^(

[ACM] hdu 5147 Sequence II (树状数组,前缀和,后缀和)

Sequence II Problem Description Long long ago, there is a sequence A with length n. All numbers in this sequence is no smaller than 1 and no bigger than n, and all numbers are different in this sequence. Please calculate how many quad (a,b,c,d) satis

Codeforces1076E. Vasya and a Tree(dfs+离线+树状数组维护)

题目链接:传送门 题目: E. Vasya and a Tree time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Vasya has a tree consisting of n vertices with root in vertex 1. At first all vertices has 0 written on it.

HDU 5869 Different GCD Subarray Query (GCD种类预处理+树状数组维护)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5869 问你l~r之间的连续序列的gcd种类. 首先固定右端点,预处理gcd不同尽量靠右的位置(此时gcd种类不超过loga[i]种). 预处理gcd如下代码,感觉真的有点巧妙... 1 for(int i = 1; i <= n; ++i) { 2 int x = a[i], y = i; 3 for(int j = 0; j < ans[i - 1].size(); ++j) { 4 int g

2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ&#39;s Salesman 【离散化+树状数组维护区间最大值】

题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 919    Accepted Submission(s): 290 Problem Description YJJ is a salesman who h

Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) C. Fountains 【树状数组维护区间最大值】

题目传送门:http://codeforces.com/contest/799/problem/C C. Fountains time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Arkady plays Gardenscapes a lot. Arkady wants to build two new fountains. The