Login - Codeforces (Unofficial mirror site, accelerated for Chinese users)
(题目链接)
题意 : 求[l, r]区间的前k大和
#include<iostream>
#include<algorithm>
#include<string>
#include<set>
#include<map>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<unordered_map>
#include<iomanip>
#define ll long long
#define ull unsigned long long
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
#define m_p make_pair
#define pi acos(-1)
using namespace std;
const int N = 1e5 + 5;
const double eps = 1e-4;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
//const ll mod = 1000003;
inline ll qpow(ll x, ll y, ll M){ll ans=1;while(y){if(y&1)ans=ans*x%M;x=x*x%M;y=y>>1;}return ans;}
inline ll gcd(ll x, ll y){return y?gcd(y,x%y):x;}
ll n, m, a[N], num;
struct node{
ll ls, rs, sum, anssum;
}tree[N<<5];
ll rt[N], sz;
void update(ll l, ll r, ll &x, ll y, ll p)
{
x = ++sz;
tree[x] = tree[y];
tree[x].sum++;
tree[x].anssum += p;
if(l == r)
return;
ll mid = (l + r) >> 1;
if(p <= mid)
update(l, mid, tree[x].ls, tree[y].ls, p);
else
update(mid + 1, r, tree[x].rs, tree[y].rs, p);
}
ll query(ll l, ll r, ll x, ll y, ll k)
{
ll temp = tree[tree[y].rs].sum - tree[tree[x].rs].sum;
ll ansr = tree[tree[y].rs].anssum - tree[tree[x].rs].anssum;
if(l == r)
return l * k;//此处k相当于值为l的数量
ll mid = (l + r) >> 1;
if(temp == k)
return ansr;
else if(temp < k)
return ansr + query(l, mid, tree[x].ls, tree[y].ls, k - temp);
else
return query(mid+1, r, tree[x].rs, tree[y].rs, k);
}
void solve()
{
sz = 0;
cin>>n;
for(ll i = 1; i <= n; i++)
{
cin>>a[i];
update(1, 1000000, rt[i], rt[i-1], a[i]);
}
cin>>m;
while(m--)
{
ll l, r, k;
cin>>l>>r>>k;
ll len = r - l + 1;
cout<<query(1, 1000000, rt[l-1], rt[r], k) + len * (len + 1) * (2 * len + 1) / 6<<'\n';
}
}
signed main()
{
IOS;
//init();
ll t = 1;
cin>>t;
while(t--)
solve();
return 0;
}