トピックポータル //解像度TP HDU
目的
徐々に端部に挿入された要素がn個の場合、要素数が省略i番目の要素の挿入、[1、i)を必要とし、接頭辞[することができる。1、i]はmより大きくありません
Qの集合[1,15]
N- [1,2e5]
mは[1,1e9】
各要素WはI(i∈のN- [1])[1、M]。
データの構造
フェンウィックツリー
分析
ツリーは、2つの配列、それぞれ、番号のプレフィックスと記憶素子を維持します。まず、すべての要素の各要素契約のための良好な指標後に記録しながら、プログラムに続いて、読んで。プレスヘッダは、アレイツリーに要素を挿入します。2分後に列挙する
O(Qnlognlogn)の時間複雑さを
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int L = 200010;
ll val[L],sor[L];
struct E{
ll v;
int pos;
}sorted[L];
int Q,POS[L];
ll n,m;
ll BIT[L],bit[L];
int Len;
int lowbit(int x){return x&-x;}
bool cmp(E a,E b){return a.v<b.v;}
void change(int x,int y){
sor[x] = y;
for(int i = x;i<=L;i+=lowbit(i)){
BIT[i] += y;bit[i]++;
}
}
ll query(int k){//对前缀和的询问
ll ans = 0;
for(int i = k;i > 0; i -= lowbit(i))
ans += BIT[i];
return ans;
}
int query1(int k){//对前缀内元素个数的询问
int ans = 0;
for(int i = k;i>0;i-=lowbit(i))
ans += bit[i];
return ans;
}
int getans(int x,int M){ //前x个元素的小序前缀之和不超过M
int lo = 1,hi = n+1;
int mi;
ll sum;
while(lo < hi){
mi = (lo + hi)>>1;
sum = query(mi);
if(M <sum) hi = mi;
else lo = mi + 1;
}
--lo;
return x-query1(lo);
}
int main(){
scanf(" %d",&Q);
while(Q--){
scanf(" %lld %lld",&n,&m);
for(int i = 1;i<=n;++i) BIT[i] = bit[i] = 0;
for(int i = 1;i<=n;++i) sor[i] = 0;
for(int i = 1;i<=n;++i) {
scanf(" %lld",&val[i]);
sorted[i].v = val[i];
sorted[i].pos = i;
}
sort(sorted+1,sorted+1+n,cmp);
for(int i = 1;i<=n;++i) POS[sorted[i].pos] = i;
int ans;
for(int i = 1;i<=n;++i){
ans = getans(i-1,m-val[i]);
change(POS[i],val[i]);
printf("%d ",ans);
}
printf("\n");
}
}