反向按值建树 && 树状数组维护区间最大值
Simone and graph coloring
https://ac.nowcoder.com/acm/contest/12548/L
按值建树
反向建树
即大值在前,小值在后
这样方便求是否存在比x大的数,以及求比x大的数的最大颜色标号
树状数组维护的最大值是颜色标号的最大值
以后但凡看到,“ t组数据,每组n个数,且所有n之和不超过10^6 ” 之类的,都一律用for清空数组
#include<bits/stdc++.h>
using namespace std;
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define low(x) x&(-x)
int const N=1e6+7;
int t,n,x,ans[N],maxn; //ans表示颜色标号
ll tr[N];
void add(ll w,int p){
for(;p<=n;p+=low(p)){
tr[p]=max(tr[p],w);
}
}
ll ask(int p){
ll res=0;
for(;p>=1;p-=low(p)){
res=max(res,tr[p]);
}
return res;
}
int main(){
fio;
cin >> t;
while(t--){
cin >> n;
//memset(tr,0,sizeof tr);
for(int i=1;i<=n;++i) tr[i]=0;
maxn=0;
for(int i=1;i<=n;++i){
cin >> x;
ans[i]=ask(n-x+1)+1;
maxn=max(maxn,ans[i]);
add(ans[i],n-x+1);
}
cout << maxn << "\n";
for(int i=1;i<=n;++i){
cout << ans[i] << " ";
}
cout << "\n";
}
return 0;
}线段树和数状数组经典例题 文章被收录于专栏
线段树和数状数组经典例题

