2022 Hubei Provincial Collegiate Programming Contest

链接

link

A. Nucleic Acid Test

Floyd,非核酸点贡献为到最近核酸点的两倍,核酸点间的贡献为所有核酸点用最短路径做边权的完全图的最小生成树的边权最大值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <bits/stdc++.h>
using namespace std;
#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define fo(i,j,k) for(int i=(j),end_i=(k);i<=end_i;i++)
#define ff(i,j,k) for(int i=(j),end_i=(k);i< end_i;i++)
#define fd(i,j,k) for(int i=(j),end_i=(k);i>=end_i;i--)
#define DEBUG(x) cerr<<#x<<"="<<x<<endl
#define all(x) (x).begin(),(x).end()
#define cle(x) memset(x,0,sizeof(x))
#define lowbit(x) ((x)&-(x))
#define VI vector<int>
#define ll long long
#define ull unsigned ll
#define db double
#define lb long db
#define pb push_back
#define mp make_pair
#define fi first
#define se second
template<class T>inline void read(T &x)
{
x=0; char ch=getchar(); bool f=0;
for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
if(f) x=-x;
}
template<class T,class... V>
inline void read(T &a,V&... b){read(a); read(b...);}
#define CASET int ___;for(read(___);___--;)
const int N=305;
const ll inf=0x3f3f3f3f3f3f3f3f;
int fa[N];
ll f[N][N];
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
int main()
{
int n,m,k,t;
read(n,m,k,t);
if(!t) return printf("-1\n")&0;
memset(f,0x3f,sizeof(f));
fo(i,1,n) f[i][i]=0;
fo(i,1,m)
{
int x,y,z; read(x,y,z);
f[x][y]=f[y][x]=z;
}
fo(k,1,n) fo(i,1,n) fo(j,1,n) if(f[i][j]>f[i][k]+f[k][j]) f[i][j]=f[i][k]+f[k][j];
fo(i,1,n) fo(j,i+1,n) if(f[i][j]==inf) return printf("-1\n")&0;
ll ans=0;
VI p;
for(;k--;) {int x; read(x); p.pb(x);}
fo(i,1,n)
{
ll sum=inf;
for(int x:p) sum=min(sum,f[x][i]);
if(sum==inf) return printf("-1\n")&0;
ans=max(ans,sum*2);
}
DEBUG(ans);
vector<array<ll,3>> edges;
for(int x:p)
for(int y:p)
if(x<y&&f[x][y]!=inf)
edges.pb({f[x][y],x,y});
sort(all(edges));
fo(i,1,n) fa[i]=i;
for(auto [z,x,y]:edges)
{
x=find(x); y=find(y);
if(x!=y) fa[x]=y,ans=max(ans,z);
}
for(int x:p) if(find(x)!=find(p[0])) {printf("-1\n"); return 0;}
printf("%lld\n",(ans+t-1)/t);
return 0;
}

D. Transition

性质:

  • 不会有 $j-i\geq 3$ 的点。
  • 一个 $j-i=2$ 的点可以被两个翻转代替。
  • 两个交换操作不会重叠。

DP,设 $f_i$ 表示考虑前 $i$ 个时的(最小操作数,方案数)。从 $f_{i-1,i-2,i-3}$ 转移过来即可。

时间复杂度 $O(n)$,常数巨大。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
	#include <bits/stdc++.h>
using namespace std;
#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define fo(i,j,k) for(int i=(j),end_i=(k);i<=end_i;i++)
#define ff(i,j,k) for(int i=(j),end_i=(k);i< end_i;i++)
#define fd(i,j,k) for(int i=(j),end_i=(k);i>=end_i;i--)
#define DEBUG(x) cerr<<#x<<"="<<x<<endl
#define all(x) (x).begin(),(x).end()
#define cle(x) memset(x,0,sizeof(x))
#define lowbit(x) ((x)&-(x))
#define VI vector<int>
#define ll long long
#define ull unsigned ll
#define db double
#define lb long db
#define pb push_back
#define mp make_pair
#define fi first
#define se second
template<class T>inline void read(T &x)
{
x=0; char ch=getchar(); bool f=0;
for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
if(f) x=-x;
}
template<class T,class... V>
inline void read(T &a,V&... b){read(a); read(b...);}
#define CASET int ___;for(read(___);___--;)
const int N=3e5+5;
const ll mod=1e9+7;
inline ll Add(ll x,ll y){x+=y; return (x<mod)?x:x-mod;}
inline ll Dec(ll x,ll y){x-=y; return (x<0)?x+mod:x;}
inline ll Mul(ll x,ll y){return x*y%mod;}
inline ll Pow(ll x,ll y)
{
y%=(mod-1);ll ans=1;for(;y;y>>=1,x=x*x%mod)if(y&1) ans=ans*x%mod;
return ans;
}
struct node{
int cnt;
ll sum;
friend inline node operator+(const node &A,const node &B)
{
if(A.cnt==B.cnt)
return {A.cnt,Add(A.sum,B.sum)};
else if(A.cnt<B.cnt)
return A;
else return B;
}
friend inline node operator+(node A,int k)
{
return {A.cnt+k,A.sum};
}
};

int main()
{
int n;
char s[N],t[N];
scanf("%d\n%s\n%s",&n,s+1,t+1);
VI a(n+1),b(n+1);
vector<node> f(n+1);
fo(i,1,n) a[i]=s[i]-'0',b[i]=t[i]-'0';
f[0]={0,1};
f[1]={a[1]^b[1],1};
fo(i,2,n)
{
f[i]={n+n,0};
f[i]=f[i]+(f[i-1]+(a[i]^b[i]));
f[i]=f[i]+(f[i-2]+1+(a[i]^b[i-1])+(a[i-1]^b[i]));
if(i>=3)
{
f[i]=f[i]+(f[i-3]+2+(a[i]^b[i-2])+(a[i-1]^b[i-1])+(a[i-2]^b[i]));
f[i]=f[i]+(f[i-3]+2+(a[i-1]^b[i-2])+(a[i]^b[i-1])+(a[i-2]^b[i]));
f[i]=f[i]+(f[i-3]+2+(a[i]^b[i-2])+(a[i-2]^b[i-1])+(a[i-1]^b[i]));
}
}
DEBUG(f[n].cnt);
printf("%lld\n",f[n].sum);
return 0;
}

E. Multigate

对于某一位,要想最后有 $1$,那么就要让后面不出现 $\text{and 0}$ 的情况,于是修改操作都要尽量往后靠,也就是修改最后面 $k$ 个 $\text{and}$ 。

时间复杂度 $O((q+n)\log a)$。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <bits/stdc++.h>
using namespace std;
#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define fo(i,j,k) for(int i=(j),end_i=(k);i<=end_i;i++)
#define ff(i,j,k) for(int i=(j),end_i=(k);i< end_i;i++)
#define fd(i,j,k) for(int i=(j),end_i=(k);i>=end_i;i--)
#define DEBUG(x) cerr<<#x<<"="<<x<<endl
#define all(x) (x).begin(),(x).end()
#define cle(x) memset(x,0,sizeof(x))
#define lowbit(x) ((x)&-(x))
#define VI vector<int>
#define ll long long
#define ull unsigned ll
#define db double
#define lb long db
#define pb push_back
#define mp make_pair
#define fi first
#define se second
template<class T>inline void read(T &x)
{
x=0; char ch=getchar(); bool f=0;
for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
if(f) x=-x;
}
template<class T,class... V>
inline void read(T &a,V&... b){read(a); read(b...);}
#define CASET int ___;for(read(___);___--;)
const int N=1e5+5;
int s[30][N][2];
int get(int x,int p)
{
int ans=0;
fo(i,0,29)
ans|=s[i][p][(x>>i)&1]<<i;
return ans;
}
int main()
{
int n,m;
read(n,m);
VI a(n+2),t(n+2),vec,b(n+1);
fo(i,1,n) read(a[i]);
fo(i,1,n)
{
read(b[i]);
if(!b[i]) vec.pb(i);
}
fo(j,0,29)
{
s[j][0][0]=0;
s[j][0][1]=1;
fo(i,1,n)
if(b[i])
{
s[j][i][0]=s[j][i-1][0]|((a[i]>>j)&1);
s[j][i][1]=s[j][i-1][1]|((a[i]>>j)&1);
}
else
{
s[j][i][0]=s[j][i-1][0]&((a[i]>>j)&1);
s[j][i][1]=s[j][i-1][1]&((a[i]>>j)&1);
}
}
fd(i,n,1) t[i]=t[i+1]|a[i];
int k=vec.size();
for(int x,y;m--;)
{
read(y,x);
if(x>=k) printf("%d\n",y|t[1]);
else printf("%d\n",get(y,vec[k-x-1])|t[vec[k-x-1]+1]);
}
return 0;
}

F. Angel

签到,答案为 $2,3,\cdots,n-1,n-1,n-2\cdots,3,2$。

H. Hamster and Multiplication

显然 $2^a3^b5^c7^d\le 10^{18}$ 不会很多,大概在几万的水平。

于是用个map记录一下,然后数位DP就好了。

J. Palindrome Reversion

显然,我们先找到第一个 $s_i\neq s_{n-i+1}$ 的点。

那么只会翻转这里面的区间。要使得翻转以后是一个回文串,当且仅当这个串是 $AAB,ABA,BAA$ 类型,其中 $A$ 为任意串,$B$ 为回文串。

哈希判断一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include <bits/stdc++.h>
using namespace std;
#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define fo(i,j,k) for(int i=(j),end_i=(k);i<=end_i;i++)
#define ff(i,j,k) for(int i=(j),end_i=(k);i< end_i;i++)
#define fd(i,j,k) for(int i=(j),end_i=(k);i>=end_i;i--)
#define DEBUG(x) cerr<<#x<<"="<<x<<endl
#define all(x) (x).begin(),(x).end()
#define cle(x) memset(x,0,sizeof(x))
#define lowbit(x) ((x)&-(x))
#define VI vector<int>
#define ll long long
#define ull unsigned ll
#define db double
#define lb long db
#define pb push_back
#define mp make_pair
#define fi first
#define se second
template<class T>inline void read(T &x)
{
x=0; char ch=getchar(); bool f=0;
for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
if(f) x=-x;
}
template<class T,class... V>
inline void read(T &a,V&... b){read(a); read(b...);}
#define CASET int ___;for(read(___);___--;)

const int N=1e5+5;
const ll mod=1004535809;
inline ll Add(ll x,ll y){x+=y; return (x<mod)?x:x-mod;}
inline ll Dec(ll x,ll y){x-=y; return (x<0)?x+mod:x;}
inline ll Mul(ll x,ll y){return x*y%mod;}
inline ll Pow(ll x,ll y)
{
y%=(mod-1);ll ans=1;for(;y;y>>=1,x=x*x%mod)if(y&1) ans=ans*x%mod;
return ans;
}
const ll base=31;
ll sf[N],sg[N],pw[N];
inline ll get_f(int l,int r)
{
if(l>r) return 0;
return Dec(sf[r],sf[l-1]*pw[r-l+1]%mod);
}
inline ll get_g(int l,int r)
{
if(l>r) return 0;
return Dec(sg[l],sg[r+1]*pw[r-l+1]%mod);
}
inline bool check_palindrome(int l,int r)
{
if(l>r) return 1;
assert(l<=r);
return get_f(l,r)==get_g(l,r);
}

pair<int,int> solve(char *s,int n)
{
pw[0]=1;
fo(i,1,n) pw[i]=pw[i-1]*base%mod;
fo(i,1,n) sf[i]=Add(sf[i-1]*base%mod,s[i]-'a');
sg[n+1]=0;
fd(i,n,1) sg[i]=Add(sg[i+1]*base%mod,s[i]-'a');
fo(i,1,n/2) if(get_f(1,i)==get_f(i+1,i+i)&&check_palindrome(i+i+1,n)) return {i+1,n};
fo(i,1,n/2) if(get_f(1,i)==get_f(n-i+1,n)&&check_palindrome(i+1,n-i)) return {1,i};
fo(i,1,n/2) if(get_f(n-i-i+1,n-i)==get_f(n-i+1,n)&&check_palindrome(1,n-i-i)) return {1,n-i};
return {-1,-1};
}

int main()
{
char s[N];
scanf("%s",s+1);
int n=strlen(s+1);
fo(i,1,n/2)
if(s[i]!=s[n-i+1])
{
auto ans=solve(s+i-1,n-(i-1)*2);
if(ans.fi!=-1) ans.fi+=(i-1),ans.se+=(i-1);
printf("%d %d\n",ans.fi,ans.se);
return 0;
}
printf("1 1\n");
return 0;
}

K. PTT

按题意照做即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <bits/stdc++.h>
using namespace std;
#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define fo(i,j,k) for(int i=(j),end_i=(k);i<=end_i;i++)
#define ff(i,j,k) for(int i=(j),end_i=(k);i< end_i;i++)
#define fd(i,j,k) for(int i=(j),end_i=(k);i>=end_i;i--)
#define DEBUG(x) cerr<<#x<<"="<<x<<endl
#define all(x) (x).begin(),(x).end()
#define cle(x) memset(x,0,sizeof(x))
#define lowbit(x) ((x)&-(x))
#define VI vector<int>
#define ll long long
#define ull unsigned ll
#define db double
#define lb long db
#define pb push_back
#define mp make_pair
#define fi first
#define se second
template<class T>inline void read(T &x)
{
x=0; char ch=getchar(); bool f=0;
for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
if(f) x=-x;
}
template<class T,class... V>
inline void read(T &a,V&... b){read(a); read(b...);}
#define CASET int ___;for(read(___);___--;)

inline db calc(int n)
{
if(n>=10000000) return 2;
else if(n<=9800000) return (0.0+n-9500000)/300000;
else return 1.0+(0.0+n-9800000)/200000;
}

int n;
double c;
int main()
{
CASET
{
scanf("%d%lf",&n,&c);
c+=calc(n);
if(c<0) c=0;
printf("%.8lf\n",c);
}
return 0;
}

L. Chtholly and the Broken Chronograph

无聊写了个分块。。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <bits/stdc++.h>
using namespace std;
#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define fo(i,j,k) for(int i=(j),end_i=(k);i<=end_i;i++)
#define ff(i,j,k) for(int i=(j),end_i=(k);i< end_i;i++)
#define fd(i,j,k) for(int i=(j),end_i=(k);i>=end_i;i--)
#define DEBUG(x) cerr<<#x<<"="<<x<<endl
#define all(x) (x).begin(),(x).end()
#define cle(x) memset(x,0,sizeof(x))
#define lowbit(x) ((x)&-(x))
#define VI vector<int>
#define ll long long
#define ull unsigned ll
#define db double
#define lb long db
#define pb push_back
#define mp make_pair
#define fi first
#define se second
template<class T>inline void read(T &x)
{
x=0; char ch=getchar(); bool f=0;
for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
if(f) x=-x;
}
template<class T,class... V>
inline void read(T &a,V&... b){read(a); read(b...);}
#define CASET int ___;for(read(___);___--;)
const int N=1e5+5;
int b[N],s[N],L[N],R[N];
ll su[N],a[N],tag[N];
int siz[N];
inline void add(int i,ll x)
{
su[i]+=x*siz[i];
tag[i]+=x;
}
void update(int x)
{
su[x]=0; siz[x]=0;
fo(i,L[x],R[x])
{
if(s[i]) a[i]+=tag[x];
if(s[i]) siz[x]++;
su[x]+=a[i];
}
tag[x]=0;
}
int main()
{
int n,q;
read(n,q);
int blo_siz=314;
fo(i,1,n) read(a[i]);
fo(i,1,n) b[i]=i/blo_siz+1;
fo(i,1,n) read(s[i]);
fo(i,1,n)
{
if(!L[b[i]]) L[b[i]]=i;
R[b[i]]=i;
}
fo(i,1,b[n]) update(i);
for(int opt,l,r,x;q--;)
{
read(opt);
if(opt<=2)
{
read(x);
update(b[x]);
s[x]^=1;
update(b[x]);
}
else if(opt==3)
{
read(l,r,x);
if(b[l]==b[r])
{
fo(i,l,r) if(s[i]) a[i]+=x;
update(b[l]);
}
else
{
fo(i,b[l]+1,b[r]-1) add(i,x);
fo(i,l,R[b[l]]) if(s[i]) a[i]+=x;
fo(i,L[b[r]],r) if(s[i]) a[i]+=x;
update(b[l]); update(b[r]);
}
}
else
{
read(l,r);
ll sum=0;
if(b[l]==b[r])
{
fo(i,l,r) sum+=a[i]+(s[i]?tag[b[i]]:0ll);
}
else
{
fo(i,b[l]+1,b[r]-1) sum+=su[i];
fo(i,l,R[b[l]]) sum+=a[i]+(s[i]?tag[b[i]]:0ll);
fo(i,L[b[r]],r) sum+=a[i]+(s[i]?tag[b[i]]:0ll);
}
printf("%lld\n",sum);
}
}
return 0;
}

M. Super Star Spectacle

这题假了。是个论文题,不太会。。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <bits/stdc++.h>
using namespace std;
#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define fo(i,j,k) for(int i=(j),end_i=(k);i<=end_i;i++)
#define ff(i,j,k) for(int i=(j),end_i=(k);i< end_i;i++)
#define fd(i,j,k) for(int i=(j),end_i=(k);i>=end_i;i--)
#define DEBUG(x) cerr<<#x<<"="<<x<<endl
#define all(x) (x).begin(),(x).end()
#define cle(x) memset(x,0,sizeof(x))
#define lowbit(x) ((x)&-(x))
#define VI vector<int>
#define ll long long
#define ull unsigned ll
#define db double
#define lb long db
#define pb push_back
#define mp make_pair
#define fi first
#define se second
template<class T>inline void read(T &x)
{
x=0; char ch=getchar(); bool f=0;
for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
if(f) x=-x;
}
template<class T,class... V>
inline void read(T &a,V&... b){read(a); read(b...);}
#define CASET int ___;for(read(___);___--;)

const int N=3e5+5;
int n,ans;
int mx[N],mx2[N],cnt[N],f[N];
vector<int> adj[N];
void dfs1(int u,int pre)
{
mx[u]=0,mx2[u]=0;
for(int v:adj[u])
if(v!=pre)
{
dfs1(v,u);
if(f[v]>=mx[u])
{
if(mx2[u]==mx[u]) cnt[u]++;
else cnt[u]=1;
mx2[u]=mx[u],mx[u]=f[v];
}
else if(f[v]>mx2[u]) mx2[u]=f[v],cnt[u]=1;
else if(f[v]==mx2[u]) cnt[u]++;
}
if(mx[u]==0) f[u]=1;
else f[u]=mx[u]+(mx[u]==mx2[u]);
}
void dfs2(int u,int pre,int g)
{
for(int v:adj[u])
if(v!=pre)
{
int tmp=mx[u]==f[v]?mx2[u]:mx[u];
if(mx[u]==f[v])
{
tmp=max(g,mx2[u]);
dfs2(v,u,tmp+(g==mx2[u]||(cnt[u]>1&&g<mx2[u])));
}
else
{
if(g>mx[u]) dfs2(v,u,g);
else if(g==mx[u]) dfs2(v,u,g+1);
else if(mx2[u]==f[v]) dfs2(v,u,mx[u]+(mx[u]==mx2[u]&&cnt[u]>1));
}
}
if(g>=mx[u]) mx2[u]=mx[u],mx[u]=g;
else if(g>mx2[u]) mx2[u]=g;
ans=min(ans,mx[u]+(mx[u]==mx2[u]));
}

int main()
{
read(n);
fo(i,2,n)
{
int x,y; read(x,y);
adj[x].pb(y); adj[y].pb(x);
}
dfs1(1,0);
ans=1e9;
dfs2(1,0,0);
printf("%d\n",ans);
return 0;
}

$w=p_u^{a_u\times b_{x_1}\times b_{x_2}\times \cdots \times b_{x_k}}$

如果 $w\bmod p_{x_k}^{a_{x_k}}=0$,那么 $p_u=p_{x_k}$ 且 $a_u\times b_{x_1}\times b_{x_2}\times \cdots \times b_{x_k}\geq a_{x_k}$。

dfs,对于第 $i$ 个点,在