You're given a permutation aa of length nn (1 \le n \le 10^51≤n≤105).
For each i \in [1,n]i∈[1,n], construct a sequence s_isi by the following rules:
Consider two sequences C = [c_1, c_2, ... c_n]C=[c1,c2,...cn] and D=[d_1, d_2, ..., d_n]D=[d1,d2,...,dn], we say the weight of CC is higher than that of DD if and only if there exists an integer kk such that 1 \le k \le n1≤k≤n, c_i=d_ici=di for all 1 \le i < k1≤i
If for each i \in [1,n]i∈[1,n], c_i=d_ici=di, the weight of CC is equal to the weight of DD.
For each i \in [1,n]i∈[1,n], print the number of non-zero elements of s_isi separated by a space.
It's guaranteed that there is only one possible answer.
There are multiple test cases.
The first line contains one integer T(1 \le T \le 20)T(1≤T≤20), denoting the number of test cases.
Each test case contains two lines, the first line contains two integers nn and kk (1 \le n,k \le 10^51≤n,k≤105), the second line contains nn distinct integers a_1, a_2, ..., a_na1,a2,...,an (1 \le a_i \le n1≤ai≤n) separated by a space, which is the permutation aa.
For each test case, print one line consists of nn integers |s_1|, |s_2|, ..., |s_n|∣s1∣,∣s2∣,...,∣sn∣ separated by a space.
|s_i|∣si∣ is the number of non-zero elements of sequence s_isi.
There is no space at the end of the line.
样例输入复制
2
3 1
3 2 1
7 2
3 1 4 6 2 5 7
样例输出复制
1 2 3
1 1 2 3 2 3 3
题意:第一行给出t(测试组数),接下来每组数据,第一行给出n(下一行数列的长度:数的个数),k(每次要查询的区间半径) ,第二行给出n个数,即数列a[],然后每次对于长度等同于n的每个数都是1的数列b[],数据给出的数列中每个数的数值(即a[i].val)为每次要修改的在b[]中的位置,该位置的数要加上以a[]中这个数为中心,半径k的区间内比中心的这个数小的最大的数的数值(设为ans)所表示的位置处的b[]的数值(即:b[a[i].val]+=b[ans]),这样从a[]中的数值(即在b[]中的位置)从小到大开始依次修改b[],最终将b[]顺序输出即可。
思路:根据a[]初始的数列建立线段树并维护区间最大值,按a[]中数值从大到小的顺序依次修改当前数a[i].val对应的在线段树中对应的位置的值为0并用map记录其对应的ans(将中心的这个数记为0后,用线段树查询区间最大值即为半径k的区间内比中心的这个数小的最大的数的数值ans),最后按b[]中位置(即a[]的数值)从小到大依次对b[]进行操作(因为每次要修改的在b[]中某位置i的数要加上以a[]中这个数为中心,半径k的区间内比中心的这个i小的最大的数的数值(设为ans)所表示的位置处的b[]的数值,所以每次i位置要加的数的位置一定在i位置之前,因此按b[]中位置(即a[]的数值)从小到大依次对b[]进行操作就保证了每次加的数一定为那个位置改完后最终确定的数),最后将b[]顺序输出即可。
完整代码:
#include
#define int long long
using namespace std;
const int mxn=1e5+5;
int t,n,k,b[mxn],tree[mxn<<2];
typedef struct point
{
int id,val;
}pi;
pi a[mxn];
mapmp;
int cmp(pi a,pi b)
{
return a.val>b.val;
}
int cmp2(pi a,pi b)
{
return a.val>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
pushup(p);
}
void modify(int p,int l,int r,int pos)
{
if(l==r)
{
tree[p]=0;
return;
}
int mid=(l+r)>>1;
if(pos<=mid)
{
modify(p<<1,l,mid,pos);
}
else{
modify(p<<1|1,mid+1,r,pos);
}
pushup(p);
}
int query(int p,int l,int r,int a,int b)
{
if(l>=a&&r<=b)
{
return tree[p];
}
int mid=(l+r)>>1;
if(b<=mid)
{
return query(p<<1,l,mid,a,b);
}
if(a>mid)
{
return query(p<<1|1,mid+1,r,a,b);
}
return max(query(p<<1,l,mid,a,mid),query(p<<1|1,mid+1,r,mid+1,b));
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>t;
while(t--)
{
cin>>n>>k;
mp.clear();
for(int i=1;i<=n;i++)
b[i]=1;
for(int i=1;i<=n;i++)
a[i].id=a[i].val=0;
for(int i=1;i<=n;i++)
{
cin>>a[i].val;
a[i].id=i;
}
build(1,1,n);
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
modify(1,1,n,a[i].id);
int l=a[i].id-k,r=a[i].id+k;
if(l<1)
l=1;
if(r>n)
r=n;
int ans=query(1,1,n,l,r);
mp[a[i].val]=ans;
}
sort(a+1,a+n+1,cmp2);
for(int i=1;i<=n;i++)
b[a[i].val]+=b[mp[a[i].val]];
for(int i=1;i<=n-1;i++)
cout<