反向按值建树 && 树状数组维护区间最大值

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;
}
线段树和数状数组经典例题 文章被收录于专栏

线段树和数状数组经典例题

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务