专栏文章
ARC184D Erase Balls 2D 题解
AT_arc184_d题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minhdw6v
- 此快照首次捕获于
- 2025/12/02 02:26 3 个月前
- 此快照最后确认于
- 2025/12/02 02:26 3 个月前
将所有球按照 排序,那么第 个球满足 。显然选择的球的顺序并不重要,我们只需要明确哪些球被选了。为了方便,我们在 和 处各添加一个球,并强制选择这两个球。
设选择的球所组成的集合为 ,那么显然有 。
设剩余的球所组成的集合为 :
- 对于 且 ,设 ,则显然有 ;
- 对于 ,设 ,则显然有 或 。
直接对本质不同的 进行计数比较困难,因此可以转化计数对象,对选择的球所组成的集合 进行计数。
显然不漏容易做到,于是问题变成了如何做到不重。考虑把 的贡献转化到满足下列条件的集合 上:
- ;
- 对于任意 ,;换句话说,即再选择任意一个球都会导致 变化。
显然满足条件的集合 是唯一的,因为了第二个条件相当于要求了集合 是极大的。
于是现在只需要统计有多少个集合 满足上面的条件即可。设 表示考虑完前 个球且选择了第 个球的满足条件的集合 的数量。转移时枚举 且 的整数 ,表示上一个选择的球为 ,判断是否能从 转移到 :
- 若存在 ,使得对于任意 都不满足 且对于任意 都不满足 (即选择 不会导致 变化),则不能从 转移到 ,否则可以从 转移到 。
于是做一个二维前缀和即可 检验是否能从 转移到 。总时间复杂度 。
Cconst int N=305,mod=998244353;
int n,v[N],s[N][N],f[N];
void add(int &a,int b){
a+=b;
if(a>=mod) a-=mod;
}
bool check(int ax,int ay,int bx,int by){
return s[ax][ay]-s[ax][by-1]-s[bx-1][ay]+s[bx-1][by-1]==1;
}
void solve(){
cin>>n,s[1][n+2]++,s[n+2][1]++,v[1]=n+2,v[n+2]=1;
for(int i=1,x,y;i<=n;i++) cin>>x>>y,x++,y++,v[x]=y,s[x][y]++;
for(int x=1;x<=n+2;x++) for(int y=1;y<=n+2;y++) s[x][y]=s[x][y]+s[x-1][y]+s[x][y-1]-s[x-1][y-1];
f[1]=1;
for(int i=2;i<=n+2;i++){
for(int j=i-1;j>=1;j--){
if(v[j]<v[i]) continue;
bool flag=1;
for(int k=j+1;k<i;k++){
if(check(k,v[k],j,v[i])&&check(i,v[j],k,v[k])){
flag=0;
break;
}
}
if(flag) add(f[i],f[j]);
}
}
cout<<f[n+2]<<endl;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...