P4229/P11288/AT_abc262_h 题解
题目链接:P4229 [清华集训 2017] 某位歌姬的故事,P11288 [COTS 2017] 模板 Z1,ABC262Ex - Max Limited Sequence
对值域 $ n $ 离散化,考虑每个位置被若干个区间覆盖然后有一个最小值,然后实际上只有两种状态,一种是取到顶,一种是不取,然后对区间排序一下就可以做 dp,$ dp[i][j] $ 表示考虑前 $ i $ 个区间上一个取到顶的位置在 $ j $,对于新的位置 $ k $ 可以将 $ i-1 $ 中所有合法的位置都转移过来然后乘至少有一个取到顶的方案数,其他位置乘不取到顶的方案数,然后就做完了。
代码(输入格式以 P4229 为准):
#include<bits/stdc++.h>
#define time(null) chrono::steady_clock::now().time_since_epoch().count()
#define int long long
#define uint unsigned long long
#define debug() cout<<"come here\n"
#define INF 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
#define pb push_back
#define Code return
#define by 0
#define MCYYDS ;
using namespace std;
int qpow(int a,int b,int p=INF){int ret=1;while(b){if(b&1)ret=(ret*a)%p;a=(a*a)%p;b>>=1;}return ret;}
inline int read(){int ret=0,f=1;char ch=getchar();while(ch<'0'||ch>'9')f=(ch=='-'?-1:f),ch=getchar();while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+(ch^48),ch=getchar();return ret*f;}
inline void write(int x){if(x<0){putchar('-');write(-x);return ;}if(x>9)write(x/10);putchar((char)(x%10+48));}
inline void writech(int x,char ch){write(x);putchar(ch);}
const int mod=998244353;
struct dsu{
vector<int> fa;
void init(int n)
{
fa.resize(n);
for(int i=1;i<n;i++)
{
fa[i]=i;
}
}
int find(int x)
{
return fa[x]==x?x:fa[x]=find(fa[x]);
}
};
struct ask{
int l,r,x,ql,qr;
};
struct node{
vector<int> blk,id;
};
vector<ask> q;
bool cmp(int x,int y)
{
return q[x].x<q[y].x;
}
signed main()
{
// ios::sync_with_stdio(0);
// cin.tie(0);
// cout.tie(0);
int T=read();
while(T--)
{
int n=read(),m=read(),k=read();
q.assign(m,{0,0,0,0,0});
vector<int> lsh;
lsh.pb(1);
lsh.pb(n+1);
for(int i=0;i<m;i++)
{
q[i].l=read(),q[i].r=read(),q[i].x=read();
lsh.pb(q[i].l);
lsh.pb(q[i].r+1);
}
sort(lsh.begin(),lsh.end());
lsh.erase(unique(lsh.begin(),lsh.end()),lsh.end());
int cnt=lsh.size()-1;
for(int i=0;i<m;i++)
{
q[i].ql=lower_bound(lsh.begin(),lsh.end(),q[i].l)-lsh.begin();
q[i].qr=lower_bound(lsh.begin(),lsh.end(),q[i].r+1)-lsh.begin()-1;
}
vector<int> ord(m);
for(int i=1;i<m;i++)
{
ord[i]=i;
}
sort(ord.begin(),ord.end(),cmp);
vector<int> up(cnt,k);
dsu ds;
ds.init(cnt+1);
for(auto id:ord)
{
int cur=ds.find(q[id].ql);
while(cur<=q[id].qr)
{
up[cur]=q[id].x;
ds.fa[cur]=ds.find(cur+1);
cur=ds.find(cur);
}
}
map<int,node> mp;
for(int i=0;i<cnt;i++)
{
mp[up[i]].blk.pb(i);
}
for(int i=0;i<m;i++)
{
mp[q[i].x].id.pb(i);
}
int ans=1;
bool flag=1;
for(auto &nod:mp)
{
int v=nod.first;
vector<int> &blk=nod.second.blk;
int s=blk.size();
vector<int> mx(s+1,0);
for(auto id:nod.second.id)
{
int l=lower_bound(blk.begin(),blk.end(),q[id].ql)-blk.begin()+1,r=upper_bound(blk.begin(),blk.end(),q[id].qr)-blk.begin();
if(l>r)
{
flag=0;
break;
}
mx[r]=max(mx[r],l);
}
if(!flag)break;
if(v==1)continue;
vector<int> dp(s+1,0);
dp[0]=1;
int sum=1,a=1,b=1,inv=qpow(v-1,mod-2,mod);
int l=0,r=0;
for(int i=1;i<=s;i++)
{
a=a*qpow(v-1,lsh[blk[i-1]+1]-lsh[blk[i-1]],mod)%mod;
b=b*qpow(inv,lsh[blk[i-1]+1]-lsh[blk[i-1]],mod)%mod;
dp[i]=(qpow(v,lsh[blk[i-1]+1]-lsh[blk[i-1]],mod)-qpow(v-1,lsh[blk[i-1]+1]-lsh[blk[i-1]],mod)+mod)%mod*sum%mod*b%mod;
sum=sum*qpow(v,lsh[blk[i-1]+1]-lsh[blk[i-1]],mod)%mod;
r=max(r,mx[i]);
while(l<r)
{
sum=(sum-dp[l]*a%mod+mod)%mod;
l++;
}
}
ans=ans*sum%mod;
}
if(!flag)puts("0");
else writech(ans,'\n');
}
Code by MCYYDS
}

浙公网安备 33010602011771号