迟到一年的补题,思路和其他人大同小异:建树,然后染色

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
const int N=1e6+7;
typedef long long ll;
#define endl '\n'
//#define int long long
#define PA pair<int,int>
vector<int>G[N];
priority_queue<PA>q;
map<int,int>mp;
string s;
int fa[N];
int n;
void build(){//建树
    int now=0,son=1;//初始的now是个空节点,而son是第一个节点
    for(auto x:s){
        if(x=='('){//建立新节点
            G[now].push_back(son);
            fa[son]=now;
            now=son;
            son++;
        }else now=fa[now];//回退到父节点
    }
}
queue<PA>tmp;
int ans[N];//染色结果
bool solve2(){
    for(int i=0;i<=n;i++){//依次遍历各个节点的子节点
        for(auto son:G[i]){
            if(q.empty())return 0;//染不了
            PA x=q.top();
            q.pop();//取数量最多的颜色
            x.first-=1;//使用该颜色的消耗
            ans[son]=x.second;//染色
            if(x.first)tmp.push(x);//如果该颜色没用完,不能直接回到q,因为同一个点的子节点不能同色
        }
        while(!tmp.empty()){
            q.push(tmp.front());
            tmp.pop();
        }
    }
    return 1;//成功完成染色
}
void solve(){
    cin>>n>>s;
    int x;
    for(int i=1;i<=n;i++){
        cin>>x;
        mp[x]++;
    }//统计各颜色火车数量
    for(auto [a,b]:mp)q.push({b,a});
    build();//建树
    if(solve2()){//染色
        cout<<"YES"<<endl;
        for(int i=1;i<=n;i++)cout<<ans[i]<<" ";
    }else cout<<"NO"<<endl;
}
signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t=1;
    //cin>>t;
    while(t--)solve();
}