QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#679295#9526. Subsequence Countingucup-team3161#ML 33ms16784kbC++176.1kb2024-10-26 17:18:312024-10-26 17:18:31

Judging History

你现在查看的是最新测评结果

  • [2024-10-26 17:18:31]
  • 评测
  • 测评结果:ML
  • 用时:33ms
  • 内存:16784kb
  • [2024-10-26 17:18:31]
  • 提交

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 ...

output:


result: