题意:小B有一个序列,包含N个1~K之间的整数。他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数。小B请你帮助他回答询问。
就是求区间不同数字个数的平方和
注意平方数可以拆开从1-n 递推。。。
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define ll long long #define pb push_back #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define inf 0x3f3f3f3f #define lson l,m,pos<<1 #define rson m+1,r,pos<<1|1 const int N=1e5+6; ll a[N],sum[N]; struct node { ll l,r,id; }s[N]; ll anss[N],ans,block; bool cmp(node a,node b) { return (a.l/block)==(b.l/block)?a.r<b.r:a.l<b.l; } void del(int x) { sum[a[x]]--; ans-=2*sum[a[x]]+1; } void add(int x) { sum[a[x]]++; ans+=2*sum[a[x]]-1; } int n,m,k; int main() { cin>>n>>m>>k; block=sqrt(n); rep(i,1,n) RI(a[i]); rep(i,1,m) scanf("%lld%lld",&s[i].l,&s[i].r),s[i].id=i; sort(s+1,s+1+m,cmp); int l=1,r=0;//指针 rep(i,1,m) { ll L=s[i].l,R=s[i].r;//范围 while(l<L)del(l++); while(r>R)del(r--); while(l>L)add(--l); while(r<R)add(++r); anss[s[i].id]=ans; } rep(i,1,m) cout<<anss[i]<<endl; return 0; }