题意:
有 $n$ 个 $K$ 维向量,若向量A只要有任意一维大于向量B,则认为A可能打败B,将n个向量一个一个加入,求问对于每次加完后的向量集合:有几个向量可能活到最后。
解法:
考虑如果A可以打败B,则A到B连边,对得到的图tarjan,可以发现可能活到最后的向量在同一强联通分量。
考虑加入一个向量x,当x的每一维都大于给定强连通分量的Max,或都小于Min时,x才不能加入当前强连通分量。
这样可以发现,最终强连通分量构成一条链,用set维护这条链,每次lower_bound合并即可。
#include <bits/stdc++.h> #define LL long long #define LD double #define FOR(i,a,b) for (int i = (a);i <= (b); i++) #define DFOR(i,a,b) for (int i = (a);i >= (b); i--) #define debug(x) cerr << "debug: " << (#x) << " = " << (x) <<endl; #define PI acos(-1) #define mp make_pair #define pb push_back #define itr iterator #define bit(x) (1LL<<(x)) #define lb(x) ((x)&(-x)) #define sqr(x) ((x)*(x)) #define gn 3 #define l(x) ch[x][0] #define r(x) ch[x][1] #define y0 Y0 #define y1 Y1 #define y2 Y2 #define fir first #define sec second using namespace std; const int N = 50010; int n,K; struct node { int M[10], m[10], sum; bool operator < (const node &tmp)const { FOR(i, 0, K-1) if(M[i] > tmp.m[i]) return false; return 1 ; } }; multiset<node> tp; int main() { scanf("%d %d", &n, &K); node tmp; FOR(i, 1, n) { FOR(i, 0, K-1) { scanf("%d", &tmp.m[i]); tmp.M[i] = tmp.m[i]; } tmp.sum = 1; auto xx = tp.lower_bound(tmp); while(xx != tp.end() && !(tmp < *xx)) { FOR(i, 0, K-1) { tmp.m[i] = min(tmp.m[i], xx->m[i]); tmp.M[i] = max(tmp.M[i], xx->M[i]); } tmp.sum += xx->sum; tp.erase(xx++); } tp.insert(tmp); printf("%d ", tp.rbegin()->sum); } return 0; }