题目:

#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小问题