QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#679295 | #9526. Subsequence Counting | ucup-team3161# | ML | 33ms | 16784kb | C++17 | 6.1kb | 2024-10-26 17:18:31 | 2024-10-26 17:18:31 |
Judging History
answer
#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(int i=(a);i>=(b);--i)
#define SZ(x) ((int)((x).size()))
#define ALL(x) (x).begin(),(x).end()
//#define int long long
using namespace std;
inline int read()
{
int x;cin>>x;return x;
}
#define mod 998244353
struct modint{
unsigned int x;
modint(int o=0){x=o;}
modint &operator = (int o){return x=o,*this;}
modint &operator +=(modint o){return x=x+o.x>=mod?x+o.x-mod:x+o.x,*this;}
modint &operator -=(modint o){return x=x<o.x?x-o.x+mod:x-o.x,*this;}
modint &operator *=(modint o){return x=1ll*x*o.x%mod,*this;}
modint &operator ^=(int b){
modint a=*this,c=1;
for(;b;b>>=1,a*=a)if(b&1)c*=a;
return x=c.x,*this;
}
modint &operator /=(modint o){return *this *=o^=mod-2;}
friend modint operator +(modint a,modint b){return a+=b;}
friend modint operator -(modint a,modint b){return a-=b;}
friend modint operator *(modint a,modint b){return a*=b;}
friend modint operator /(modint a,modint b){return a/=b;}
friend modint operator ^(modint a,int b){return a^=b;}
friend bool operator ==(modint a,modint b){return a.x==b.x;}
friend bool operator !=(modint a,modint b){return a.x!=b.x;}
bool operator ! () {return !x;}
modint operator - () {return x?mod-x:0;}
bool operator <(const modint&b)const{return x<b.x;}
};
inline modint qpow(modint x,int y){return x^y;}
vector<modint> fac,ifac,iv;
inline void initC(int n)
{
if(iv.empty())fac=ifac=iv=vector<modint>(2,1);
int m=iv.size(); ++n;
if(m>=n)return;
iv.resize(n),fac.resize(n),ifac.resize(n);
For(i,m,n-1){
iv[i]=iv[mod%i]*(mod-mod/i);
fac[i]=fac[i-1]*i,ifac[i]=ifac[i-1]*iv[i];
}
}
inline modint C(int n,int m){
if(m<0||n<m)return 0;
return initC(n),fac[n]*ifac[m]*ifac[n-m];
}
inline modint sign(int n){return (n&1)?(mod-1):(1);}
#define fi first
#define se second
#define pb push_back
#define mkp make_pair
typedef pair<int,int>pii;
typedef vector<int>vi;
template<class info>
struct segt1{
int n;
vector<info>tr;
vector<int>leaf;
void init(vector<info>a){
n=a.size(); assert(n);
tr.assign(4<<__lg(n),info());
leaf.resize(n);
function<void(int,int,int)>build=[&](int p,int l,int r){
if(l==r)return leaf[l]=p,tr[p]=a[l],void();
int mid=l+r>>1;
build(p<<1,l,mid),build(p<<1|1,mid+1,r),up(p);
};
build(1,0,n-1);
}
void init(int _n){
init(vector<info>(_n));
}
void up(int p){
tr[p]=tr[p<<1]+tr[p<<1|1];
}
void upd(int x,info y){
--x;
x=leaf[x],tr[x]=y;
while(x>>=1)up(x);
}
info ask(int p,int l,int r,int ql,int qr){
if(l>=ql&&r<=qr)return tr[p];
int mid=l+r>>1;
if(qr<=mid)return ask(p<<1,l,mid,ql,qr);
if(ql>mid)return ask(p<<1|1,mid+1,r,ql,qr);
return ask(p<<1,l,mid,ql,qr)+ask(p<<1|1,mid+1,r,ql,qr);
}
info ask(int l,int r){
if(l>r)return info();
--l,--r;
return ask(1,0,n-1,l,r);
}
};
#define maxn 500055
#define inf 0x3f3f3f3f
int n,m;
int str[15];
struct mat{
modint a[11][11];
mat(){
}
modint *operator [](int x){
return a[x];
}
void init1(){
memset(a,0,sizeof a);
For(i,0,m)a[i][i]=1;
}
};
mat operator *(mat a,mat b){
mat c;
For(i,0,m)
For(j,i,m)
For(k,j,m)
{
c[i][k]+=a[i][j]*b[j][k];
}
return c;
}
mat gen(int x){
mat a;
For(i,0,m) a[i][i]=1;
For(i,0,m-1) if(str[i]==x) a[i][i+1]=1;
return a;
}
mat I;
struct node{
int len;
mat t;
};
void exgcd(int a,int b,int&x,int&y){
if(!b)return x=1,y=0,void();
exgcd(b,a%b,y,x),y-=a/b*x;
}
int getinv(int x,int n){
int tmp,res;
exgcd(n,x,tmp,res);
return (res%n+n)%n;
}
int t[maxn],tlen;
mat qpow(mat a,int b){
if(b==1) return a;
// cout<<"qpow "<<b<<"\n";
mat res; res.init1();
while(b){
if(b&1)res=res*a;
b>>=1; a=a*a;
}
return res;
}
int pos[maxn];
bool isin(int p,int l,int r){
return p>=l && p<=r;
}
struct info{
mat f;
info (mat ff=mat()){
f=ff;
}
};
info operator +(info a,info b){
a.f=a.f*b.f;
return a;
}
segt1<info>T;
mat solve(vector<node>a,int r,int n)
{
// cout<<"Solve "<<r<<" "<<n<<"\n";
if(n==1){
return a[0].t;
}
if(r*2>=n){
vector<node>b;
b.pb((node){1,a[0].t});
--a[0].len;
Rep(i,SZ(a)-1,0){
if(a[i].len) b.pb(a[i]);
}
return solve(b,n-r,n);
}
int ps=0;
tlen=0;
int n2=(n+(r-n%r)%r);
if(n!=n2) a.pb((node){n2-n,I});
vector<pii>tmp;
t[++tlen]=0;
For(i,0,SZ(a)-2){
ps+=a[i].len;
pos[i]=ps;
t[++tlen]=ps/r;
if(ps%r!=0)
tmp.pb(mkp(ps%r,i));
t[++tlen]=ps/r+1;
}
tmp.pb(mkp(r,-1));
t[++tlen]=n2/r;
sort(t+1,t+tlen+1);
tlen=unique(t+1,t+tlen+1)-t-1;
sort(tmp.begin(),tmp.end());
vector<info> sg;
{
int j=0;
int lst=0;
For(i,1,tlen-1){
while(j+1<a.size() && !isin(t[i]*r,lst,pos[j]-1))
++j,lst=pos[j-1];
// cout<<"j: "<<t[i]*r<<" "<<lst<<" "<<pos[j]-1<<"\n";
mat val=qpow(a[j].t , t[i+1]-t[i]);
sg.pb(info(val));
}
}
T.init(sg);
vector<node> res;
{
int lst=0;
for(auto [p,id]:tmp){
if(lst<p){
mat now=T.tr[1].f;
res.pb((node){p-lst,now});
lst=p;
}
if(id==-1) continue;
int ps=pos[id]/r;
ps=lower_bound(t+1,t+tlen+1,ps)-t;
T.upd(ps,info(a[id+1].t));
}
}
return solve(res,r-n%r,r);
}
void work()
{
n=read(),m=read();
I.init1();
int k=read(),l=read();
For(i,0,m-1) str[i]=read();
vector<node>a(n);
For(i,0,n-1){
a[i].len=read();
int x=read();
a[i].t=gen(x);
}
k=getinv(k,l);
mat res=solve(a,k,l);
cout<<res[0][m].x<<"\n";
}
signed main()
{
int T=1;
while(T--)work();
return 0;
}
/*
6
aabbab
aabbaa
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 5684kb
input:
4 2 17 27 3 1 10 3 6 1 10 3 1 1
output:
76
result:
ok single line: '76'
Test #2:
score: 0
Accepted
time: 0ms
memory: 5808kb
input:
5 3 1789 15150 555 718 726 72 555 1029 718 5807 726 1002 718 7240 555
output:
390415327
result:
ok single line: '390415327'
Test #3:
score: 0
Accepted
time: 0ms
memory: 5532kb
input:
1 1 1 1000000000 1000 1000000000 1000
output:
1755647
result:
ok single line: '1755647'
Test #4:
score: 0
Accepted
time: 33ms
memory: 16784kb
input:
1999 10 999999999 1000000000 944 901 986 915 979 988 947 999 969 946 198832 985 235662 982 367137 938 219700 949 166086 906 488084 905 891250 984 243743 971 253382 987 181971 935 2382 948 462701 981 4681 925 113363 916 119397 921 337742 982 427128 921 285959 986 197975 978 140753 907 167150 974 4576...
output:
211590728
result:
ok single line: '211590728'
Test #5:
score: -100
Memory Limit Exceeded
input:
2000 10 207560381 499173270 382 246 825 688 810 66 333 717 903 444 242322 825 303194 246 266460 66 133293 444 499376 688 175256 333 260041 717 202138 444 84931 688 353443 825 137750 382 333307 66 450617 810 27484 246 349436 717 45179 444 146073 810 107846 717 416816 246 255378 825 433826 688 273215 ...