QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#739235 | #9526. Subsequence Counting | sz051 | WA | 0ms | 9628kb | C++14 | 5.2kb | 2024-11-12 21:13:25 | 2024-11-12 21:13:25 |
Judging History
answer
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cassert>
#include <map>
#include <queue>
#include <set>
#include <string>
#define int long long
using namespace std;
const int md=998244353;
const __int128_t p=(((__int128_t)1)<<64)/md;
int qmod(int k){
return k>=md?k-md:k;
}
int Qmod(int k){
return qmod(k-((p*k)>>64)*md);
}
void read(int &x){
x=0;
int f=1;
char c=getchar();
while(!('0'<=c && c<='9')){
if(c=='-'){
f=-1;
}
c=getchar();
}
while('0'<=c && c<='9'){
x=(x<<3)+(x<<1)+(c^48);
c=getchar();
}
x*=f;
}
void write(int k){
if(k>9){
write(k/10);
}
putchar(k%10+'0');
}
int tp=0;
int n,m,k,l,xs[2010],rev[2010],cols[2010];
struct Matrix{
int a[11][11];
Matrix(){
memset(a,0,sizeof(a));
}
int *operator[](int k){
return a[k];
}
friend Matrix operator*(Matrix &a,Matrix &b){
Matrix res;
for(int i=0;i<=m;i++){
for(int j=0;j<=i;j++){
for(int k=0;k<=j;k++){
res[i][k]=Qmod(res[i][k]+a[i][j]*b[j][k]);
}
}
}
return res;
}
friend bool operator==(Matrix& a,Matrix& b){
for(int i=0;i<=m;i++){
for(int j=0;j<=i;j++){
if(a[i][j]!=b[i][j]){
return 0;
}
}
}
return 1;
}
friend bool operator!=(Matrix& a,Matrix& b){
for(int i=0;i<=m;i++){
for(int j=0;j<=i;j++){
if(a[i][j]!=b[i][j]){
return 1;
}
}
}
return 0;
}
void operator=(Matrix v){
memcpy(a,v.a,sizeof(a));
}
} id,trns[20],sgt[4110];
int pos[2110];
void build(int k,int l,int r){
sgt[k]=id;
if(l!=r){
int mid=(l+r)>>1;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
}
}
void pushdown(int k){
if(sgt[k]!=id){
sgt[k*2]=sgt[k]*sgt[k*2];
sgt[k*2+1]=sgt[k]*sgt[k*2+1];
sgt[k]=id;
}
}
void update(int k,int curl,int curr,int ql,int qr,Matrix &v){
if(ql>qr){
return;
}
if(ql<=curl && curr<=qr){
sgt[k]=v*sgt[k];
}else{
pushdown(k);
int mid=(curl+curr)>>1;
if(ql<=mid){
update(k*2,curl,mid,ql,qr,v);
}
if(mid<qr){
update(k*2+1,mid+1,curr,ql,qr,v);
}
}
}
void rebuild(int k,int curl,int curr){
if(curl==curr){
pos[curl]=k;
}else{
pushdown(k);
int mid=(curl+curr)>>1;
rebuild(k*2,curl,mid);
rebuild(k*2+1,mid+1,curr);
}
}
int getinv(int a,int b){
int tmp=b,phi=1;
for(int i=2;i*i<=tmp;i++){
if(tmp%i==0){
tmp/=i;
phi*=(i-1);
while(tmp%i==0){
tmp/=i;
phi*=i;
}
}
}
if(tmp!=1){
phi*=(tmp-1);
}
tmp=1;
phi--;
for(;phi;phi>>=1,a=a*a%b){
if(phi&1){
tmp=tmp*a%b;
}
}
return tmp;
}
Matrix powr(Matrix &b,int k){
Matrix res=id;
for(;k;k>>=1,b=b*b){
if(k&1){
res=res*b;
}
}
return res;
}
struct Node{
int len;
Matrix mat;
Node(){
len=0;
mat=Matrix();
}
void show(){
printf("%lldx\n",len);
for(int i=0;i<=m;i++){
putchar('[');
for(int j=0;j<=m;j++){
printf("%lld ",mat[i][j]);
}
printf("]\n");
}
}
} nds[2010];
void flip(){
Matrix tmp=nds[tp].mat;
if(nds[tp].len==1){
tp--;
}else{
nds[tp].len--;
}
reverse(nds+1,nds+tp+1);
if(nds[tp].mat==tmp){
nds[tp].len++;
}else{
nds[++tp].mat=tmp;
nds[tp].len=1;
}
}
signed main(){
for(int i=0;i<=10;i++){
id[i][i]=1;
}
read(n);
read(m);
read(k);
read(l);
k=getinv(k,l);
printf("[%lld]",k);
map<int,vector<int> > mp;
int u;
for(int i=1;i<=m;i++){
read(u);
if(mp.find(u)==mp.end()){
mp[u]=vector<int>();
cols[mp.size()]=u;
rev[u]=mp.size();
}
mp[u].push_back(i);
}
trns[0]=id;
for(int i=1;i<=mp.size();i++){
trns[i]=id;
for(auto j:mp[cols[i]]){
trns[i][j][j-1]=1;
}
}
for(int i=1;i<=n;i++){
read(nds[n-i+1].len);
read(u);
nds[n-i+1].mat=trns[rev[u]];
}
for(int i=1;i<=n;i++){
if(!tp || (nds[tp].mat!=nds[i].mat)){
nds[++tp]=nds[i];
}else{
nds[tp].len+=nds[i].len;
}
}
while(l!=1){
// printf("[%lld %lld]\n",l,k);
// for(int i=tp;i;i--){
// nds[i].show();
// }
// putchar('\n');
if(k*2>l){
k=l-k;
flip();
continue;
}
int cnt=0;
xs[++cnt]=0;
for(int i=tp;i;i--){
xs[cnt+1]=(xs[cnt]+nds[i].len)%k;
cnt++;
}
sort(xs+1,xs+cnt+1);
cnt=unique(xs+1,xs+cnt+1)-xs-1;
xs[cnt+1]=k;
build(1,1,cnt);
int cur=0;
for(int i=tp;i;i--){
int lb=cur,rb=cur+nds[i].len;
int lp=lower_bound(xs+1,xs+cnt+1,lb%k)-xs,rp=lower_bound(xs+1,xs+cnt+1,rb%k)-xs-1;
if(rp==0){
rp=cnt;
}
//printf("[%lld %lld(%lld)]",lp,rp,nds[i].len/k);
cur+=nds[i].len;
if(lp<=rp){
update(1,1,cnt,lp,rp,nds[i].mat);
Matrix tmp=powr(nds[i].mat,(nds[i].len-(xs[rp+1]-xs[lp]))/k);
sgt[1]=tmp*sgt[1];
}else{
update(1,1,cnt,lp,cnt,nds[i].mat);
update(1,1,cnt,1,rp,nds[i].mat);
Matrix tmp=powr(nds[i].mat,(nds[i].len-(xs[cnt+1]-xs[lp])-(xs[rp+1]-xs[1]))/k);
sgt[1]=tmp*sgt[1];
}
}
rebuild(1,1,cnt);
tp=0;
for(int i=1;i<=cnt;i++){
if(!tp || nds[tp].mat!=sgt[pos[cnt-i+1]]){
nds[++tp].mat=sgt[pos[cnt-i+1]];
nds[tp].len=xs[cnt-i+2]-xs[cnt-i+1];
}else{
nds[tp].len+=xs[cnt-i+2]-xs[cnt-i+1];
}
}
swap(l,k);
k=l-(k%l);
}
printf("%lld",nds[1].mat[m][0]);
return 0;
}
/*
4 2 17 27
3 1
10 3
6 1
10 3
1 1
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 0ms
memory: 9628kb
input:
4 2 17 27 3 1 10 3 6 1 10 3 1 1
output:
[8]76
result:
wrong answer 1st lines differ - expected: '76', found: '[8]76'