zoukankan      html  css  js  c++  java
  • 树状数组维护前缀和、后缀和、个数|牛牛的Link Power

    思路


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

    F题 2棵树状数组维护前缀和和个数即可

    题目地址
    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;
    } 
    
  • 相关阅读:
    Ubuntu 侧边栏和顶栏设置
    ubuntu 下安装微软字体和 console
    vim 的 auto-pairs 设置
    linux上的常用的一些操作
    断点模式
    GIT(git)简单操作
    制表符 的用法
    如何解决ASCII 字符显示不出来的情况
    01_js 快速入门
    神代码,结束进程神方法
  • 原文地址:https://www.cnblogs.com/fisherss/p/12657814.html
Copyright © 2011-2022 走看看