1 solutions

  • 0
    @ 2021-12-26 17:43:07

    思路

    很显然一眼看过去就是一道很经典的二维偏序问题,我们通过对询问存储下来然后升序排序,通过线段树或者树状数组更新并离线询问即可

    Code

    #include<bits/stdc++.h>
    #include<ctime>
    #include<cstdlib>
    using namespace std;
    #define ll long long
    const int N = 5e5+10;
    ll tree[N],a[N],ans[N],vis[N];
    ll n,m;
    
    struct Node {
    	int pos,l,r;
    }V[N];
    
    ll lowbit(ll x) {
    	return -x & x;
    } 
    
    void updata(ll x,ll k) {
    	while(x <= n) {
    		tree[x] += k;
    		x += lowbit(x);
    	}
    }
    ll query(ll x){
    	ll ans = 0;
    	while(x) {
    		ans += tree[x];
    		x -= lowbit(x);
    	}
    	return ans;
    }
    
    int main()
    {
    
    	scanf("%lld%lld",&n,&m);
    	for(int i = 1;i <= n; ++i) {
    		scanf("%lld",&a[i]);
    	}
    	ll l,r;
    	for(ll i = 1;i <= m; ++i) {
    		scanf("%lld%lld",&l,&r);
    		V[i].l = l;
    		V[i].r = r;
    		V[i].pos = i;
    	}
    	sort(V+1,V+1+m,[](Node a,Node b){return a.r == b.r?a.l < b.l:a.r < b.r;});
    	ll loc = 1;
    	for(ll i = 1;i <= m; ++i) {
    		for(ll j = loc;j <= V[i].r; ++j) {
    			if(vis[a[j]]) updata(vis[a[j]],-a[j]);
    			vis[a[j]] = j;
    			updata(j,a[j]);
    		}
    		loc = V[i].r + 1;
    		ans[V[i].pos] = query(V[i].r) - query(V[i].l - 1);
    	}
    	for(ll i = 1;i <= m; ++i) {
    		printf("%lld\n",ans[i]);
    	}
    	return 0;
     }
    
    • 1

    Information

    ID
    269
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    6
    Tags
    # Submissions
    34
    Accepted
    4
    Uploaded By