CF Round 997 题解合集
C
考虑这样一种构造:
或者是:
这里的 不是题面中的 。
但是经检查,这种构造会在 时死掉。
所以考虑特判 。
#include<bits/stdc++.h>
using namespace std;
int t,n;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--){
cin>>n;
if(n==6){
cout<<"1 1 2 3 1 2\n";
continue;
}
for(int i=1;i<=n/2;i++){
cout<<i<<' ';
}
if(n&1) cout<<n<<' ';
for(int i=(n+1)/2+1;i<=n;i++){
cout<<i-(n+1)/2<<' ';
}
cout<<'\n';
}
return 0;
}
D
看到值域 ,考虑枚举值域,将序列上的数转化为 去做。
因为对合法的区间计数不太好做,所以考虑对不合法的区间计数。
注意到,对于每个不合法区间,都存在唯一一个 ,使得令 时,区间和为 。
然后就做完了。
注意因为 限制是区间中出现过的数,所以每次加入前缀时需要考虑形成的区间中是否存在 。
复杂度 。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int t,n,ans,sum[200005],a[200005],b[200005],cnt[4000005];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int k=1;k<=10;k++){
for(int i=1;i<=n;i++){
b[i]=(a[i]<=k?-1:1);
sum[i]=sum[i-1]+b[i];
}
int j=1;
for(int i=1;i<=n;i++){
if(a[i]==k){
for(;j<=i;j++){
cnt[sum[j-1]+n]++;
}
}
ans+=cnt[sum[i]+n];
}
for(int i=0;i<=2*n;i++){
cnt[i]=0;
}
}
ans=n*(n+1)/2-ans;
cout<<ans<<'\n';
ans=0;
}
return 0;
}
E
观察发现,集合 的最大值是 ,具体构造可以考虑建立一棵二叉广义线段树。
然后考虑对这类树状物计数。
首先考虑 的情况。
设 表示 时的答案,初始 ,不难得到转移:
然后这个形式看起来很像卡特兰数,打表发现 。
然后考虑 的情况。
不难发现,对于每一条限制,相当于在二叉树的当前层,有一些区间被看成了是一个点。
因此,我们往限制中加入 和 ,答案为 。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod=998244353;
int t,n,m,ans,flag,vis[400005],cnt[400005];
struct node{
int l,r;
}h[400005];
bool cmp(node a,node b){
if(a.l!=b.l) return a.l<b.l;
else return a.r>b.r;
}
int binpow(int a,int b){
if(!b) return 1;
int res=binpow(a,b/2);
if(b&1) return res*res%mod*a%mod;
else return res*res%mod;
}
int fac[400005];
int C(int n,int m){
return fac[n]*binpow(fac[m],mod-2)%mod*binpow(fac[n-m],mod-2)%mod;
}
int H(int n){
if(n<=0) return 1;
return C(2*n,n)*binpow(n+1,mod-2)%mod;
}
stack<int> s;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--){
cin>>n>>m;
fac[0]=ans=1;
for(int i=1;i<=n*2;i++){
fac[i]=fac[i-1]*i%mod;
}
for(int i=1;i<=m;i++){
cin>>h[i].l>>h[i].r;
if(h[i].l==h[i].r) vis[h[i].l]=1;
if(h[i].l==1 && h[i].r==n) flag=1;
}
if(!flag) h[++m]=(node){1,n};
flag=0;
for(int i=1;i<=n;i++){
if(!vis[i]) h[++m]=(node){i,i};
vis[i]=0;
}
if(n==1){
cout<<1<<'\n';
continue;
}
sort(h+1,h+1+m,cmp);
for(int i=1;i<=m;i++){
while(s.size() && h[s.top()].r<h[i].l) s.pop();
if(s.size()) cnt[s.top()]++,cnt[i]++;
s.push(i);
}
cnt[1]++;
for(int i=1;i<=m;i++){
ans=ans*H(cnt[i]-2)%mod;
}
cout<<ans<<'\n';
for(int i=1;i<=m;i++){
cnt[i]=0;
}
while(s.size()) s.pop();
}
return 0;
}
本文作者:Kenma
本文链接:https://www.cnblogs.com/Kenma/p/18720875
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步