题目:
image

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=2e5+5;
struct Node{
	int l,r;
	int cnt;
};
int idx;
Node tree[maxn*40];
int root[maxn];
int build(int l,int r){
	int node=++idx;
	tree[node].cnt=0;
	if(l==r) return node;
	int mid=(l+r)/2;
	tree[node].l=build(l,mid);
	tree[node].r=build(mid+1,r);
	return node;
}
void insert(int x,int &y,int l,int r,int v){
	y=++idx;
	tree[y]=tree[x];
	tree[y].cnt++;
	if(l==r) return;
	int m=(l+r)/2;
	if(v<=m){
		insert(tree[x].l,tree[y].l,l,m,v);
	}
	else{
		insert(tree[x].r,tree[y].r,m+1,r,v);
	}
}
int query(int u,int v,int l,int r,int k){
	if(l==r) return l;
	int mid=(l+r)/2;
	int cnt=tree[tree[v].l].cnt-tree[tree[u].l].cnt;
	if(k<=cnt){
		return query(tree[u].l,tree[v].l,l,mid,k);
	}
	else{
		return query(tree[u].r,tree[v].r,mid+1,r,k-cnt);
	}
}
void init(const vector<int>& data, int n){
	idx=0; 
	root[0]=build(1,n);
	for(int i=1;i<=data.size();i++){
		int x=data[i-1];
		insert(root[i-1],root[i],1,n,x);
	}
}
int solve(int l, int r, int n) {
	int len = r - l + 1;
	int k = (len + 1) / 2; 
	return query(root[l-1], root[r], 1, n, k);
}
signed main(){
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		vector<int> data(n);
		int ans=0;
		for(int i=0;i<n;i++){
			cin>>data[i];
			ans += (i+1)*(i+1)*data[i];
		}
		init(data, n);
		for(int i=1;i<=n;i++){
			for(int j=i+2;j<=n;j+=2){
				int m = solve(i, j, n);
				ans += i*j*m;
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}```
权值线段树存的是下标,比如:如果存入[1,2,3,5,1,2],那么最底层就是[1,1]->1,[2,2]->2,[3,3]->3,[4,4]->5...处理区间最值和区间和的问题
主席树存的是值域:比如如果存[1,2,3,5,1,2]那么[1,1]->2,[2,2]->2,[3,3]->1,[4,4]->0,[5,5]->1,[1,2]->4...存的是在某个值域的数字有多少个,,处理第k小问题