UVALive - 4255(拓扑排序+构造)

mac2024-04-15  31

传送门

思路:连续和转化为前缀和之差。可以将问题转化为已知序列 a1,a2,...,an 的大小关系,求出任意一组满足条件的序列。 拓扑排序即可。

我是以sum大指向sum小的方向建边。假设入度为零的点即最大值点的值为0,那么后面的点比它小就小1。 注意sum[0]=0,0也要跑。

#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> piir; const int maxn = 10+5; const int maxm = 5e5+5; const int INF = 0x3f3f3f3f; string s; vector<int> G[maxn]; int T,n; int sum[maxn],in[maxn]; queue<int> q; void top(){ for(int i=0;i<=n;i++){ if(in[i]==0) q.push(i); } while(!q.empty()){ int u=q.front();q.pop(); for(auto v : G[u]){ sum[v] = sum[u]-1; in[v]--; if(in[v]==0) q.push(v); } } } void init(){ while(!q.empty()) q.pop(); for(int i=0;i<=n;i++) G[i].clear(); memset(sum,0,sizeof(sum)); memset(in,0,sizeof(in)); } int main(){ //freopen("in.txt","r",stdin); cin>>T; while(T--){ init(); cin>>n; cin>>s; int tot=0; for(int i=1;i<=n;i++){ for(int j=i;j<=n;j++){ if(s[tot]=='+') G[j].push_back(i-1),in[i-1]++; else if(s[tot]=='-') G[i-1].push_back(j),in[j]++; tot++; } } top(); for(int i=1;i<=n;i++){ cout<<sum[i]-sum[i-1]<<" "; } cout<<'\n'; } return 0; }

 

最新回复(0)