• codeforces 86 D


    题目链接:https://codeforces.com/contest/86/problem/D

    莫队模板题。

    莫队主要思想是对询问分块,块与块直接按左端点升序排列,块内按右端点升序排列

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 200010;
    
    int t, len, n, m, tot;
    int a[maxn], c[maxn], b[maxn];
    int L[maxn], R[maxn], pos[maxn];
    ll ans = 0;
    
    struct Query{
    	int l, r, id;
    	ll ans; 
    }q[maxn];
    
    bool cmp_L(Query a, Query b){
    	if(a.l == b.l) return a.r < b.r;
    	return a.l < b.l;
    }
    
    bool cmp_R(Query a, Query b){
    	if(a.r == b.r) return a.l < b.l;
    	return a.r < b.r;
    }
    
    bool cmp_id(Query a, Query b){
    	return a.id < b.id;
    }
    
    void add(int x){
    	ans -= 1ll * c[a[x]] * c[a[x]] * b[a[x]];
    	++c[a[x]];
    	ans += 1ll * c[a[x]] * c[a[x]] * b[a[x]];
    }
    
    void del(int x){
    	ans -= 1ll * c[a[x]] * c[a[x]] * b[a[x]];
    	--c[a[x]];
    	ans += 1ll * c[a[x]] * c[a[x]] * b[a[x]];
    }
    
    ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
    
    int main(){
    		n = read(), m = read();
    		for(int i = 1 ; i <= n ; ++i) a[i] = read(), b[i] = a[i];
    		
    		sort(b + 1, b + 1 + n);
    		tot = unique(b + 1, b + 1 + n) - b - 1;
    		for(int i = 1 ; i <= n ; ++i){
    			a[i] = lower_bound(b + 1, b + 1 + tot, a[i]) - b; 
    		}
    		
    		t = sqrt(n), len = m / t;
    		for(int i = 1 ; i <= t ; ++i){
    			L[i] = (i - 1) * len + 1;
    			R[i] = i * len;
    		}
    		if(R[t] < m) {
    			L[++t] = R[t - 1] + 1;
    			R[t] = m;
    		}
    		
    		for(int i = 1 ; i <= t ; ++i){
    			for(int j = L[i] ; j <= R[i] ; ++j){
    				pos[j] = i;
    			}
    		}
    		
    		int l, r;
    		for(int i = 1 ; i <= m ; ++i){
    			q[i].l = read(), q[i].r = read();
    			q[i].id = i;
    		} 
    		
    		sort(q + 1, q + 1 + m, cmp_L);
    		
    		for(int i = 1 ; i <= t ; ++i){
    			for(int j = 0 ; j <= tot ; ++j) c[j] = 0;
    			
    			sort(q + L[i], q + 1 + R[i], cmp_R);
    
    			ans = 0;
    			int ql = q[L[i]].l, qr = q[L[i]].r, cl = ql, cr = qr;
    			
    			for(int j = ql ; j <= qr ; ++j) ++c[a[j]];
    			
    			for(int j = 1 ; j <= tot ; ++j) ans += 1ll * c[j] * c[j] * b[j];
    			q[L[i]].ans = ans;
    			
    			for(int j = L[i] + 1 ; j <= R[i] ; ++j){
    				while(cl < q[j].l) del(cl++);
    				while(cl > q[j].l) add(--cl);
    				while(cr < q[j].r) add(++cr);
    				q[j].ans = ans;
    			}
    		}
    		
    		sort(q + 1, q + 1 + m, cmp_id);
    		for(int i = 1 ; i <= m ; ++i){
    			printf("%lld
    ", q[i].ans);
    		}
    	return 0;
    }
    
  • 相关阅读:
    Windows7共享设置
    13-运算符
    13-数据类型转换
    06-移动web之flex布局
    09-sass
    08-less预处理器
    移动端必须掌握知识点
    11-JS变量
    10-响应式
    07-rem
  • 原文地址:https://www.cnblogs.com/tuchen/p/14354496.html
Copyright © 2020-2023  润新知