题目链接:​​https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=0&problem=4169&mosmsg=Submission+received+with+ID+26578906​

将区间和拆成前缀和的差,条件转化为前缀和两两之间的大小关系,以大小关系连有向边,进行拓扑排序,按拓扑序给前缀和赋值

需要注意的是,如果两个前缀和是相等关系,需要使用并查集合并节点,不能简单地另其中一个等于另一个,因为可能有很多个前缀和节点都相等

最后注意输出格式问题

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 310;

int T, n;
int a[maxn], b[maxn];
int deg[maxn];

char ch[maxn], c[maxn][maxn];

int h[maxn], cnt = 0;
struct E{
int to, next;
}e[maxn << 1];
void add(int u, int v){
e[++cnt].to = v;
e[cnt].next = h[u];
h[u] = cnt;
}

int par[maxn];
int find(int u){
return par[u] == u ? u : par[u] = find(par[u]);
}

vector<int> path;
int in[maxn];

void topo(){
queue<int> q;

for(int i = 0 ; i <= n ; ++i){
if(!deg[i] && in[i]) {
q.push(i);
path.push_back(i);
}
}

while(!q.empty()){
int u = q.front(); q.pop();
for(int i = h[u] ; i != -1 ; i = e[i].next){
int v = e[i].to;
--deg[v];
if(!deg[v]){
q.push(v);
path.push_back(v);
}
}
}
}

ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }

int main(){
scanf("%d", &T);
while(T--){
path.clear();
memset(in, 0, sizeof(in));
memset(h, -1, sizeof(h)); cnt = 0;
memset(deg, 0, sizeof(deg));

scanf("%d", &n);
scanf("%s", ch + 1);
for(int i = 0 ; i <= n ; ++i) par[i] = i;

int pos = 1;
for(int i = 1 ; i <= n ; ++i){
for(int j = i ; j <= n ; ++j){
c[i][j] = ch[pos];
if(ch[pos++] == '0') par[j] = i - 1;
}
}

for(int i = 1 ; i <= n ; ++i){
for(int j = i ; j <= n ; ++j){
if(c[i][j] == '+'){
add(find(i - 1), find(j));
++deg[find(j)];
in[find(i - 1)] = 1;
in[find(j)] = 1;
}
if(c[i][j] == '-'){
add(find(j), find(i - 1));
++deg[find(i - 1)];
in[find(i - 1)] = 1;
in[find(j)] = 1;
}
}
}

topo();

int val = 0;
for(int i = 0 ; i < path.size() ; ++i){
b[path[i]] = val++;
}

for(int i = 1 ; i <= n ; ++i){
b[i] = b[find(i)];
if(i > 1) printf(" ");
printf("%d", b[i] - b[i - 1], (i == n) ? '\n' : ' ');
} printf("\n");
}
return 0;
}