# Selected miscellaneous questions (Fate Trilogy)

How difficult it is to find three questions about \ (fat \) in a world full of cadoli

## Today's meal at Emiya's house

A very good inclusion exclusion + \ (dp \) problem

Considering the third limitation, it is found that at most one column is illegal, so we can enumerate which column is illegal

Then the next task is to find the total number of schemes - the number of illegal schemes

First, consider how to calculate the number of illegal schemes

Let \ (s_i \) represent \ (\ sum a_{i,j} \) of each row, and \ (col \) represent the illegal column enumerated

Let \ (f_{i,j,k} \) indicate that considering row \ (I \), row \ (j \) is selected for the illegal column, and a total of \ (k \) rows are selected for the remaining columns

Then you can get the transfer

$$f_{i,j,k}=f_{i-1,j,k}+a_{i,col}\times f_{i-1,j-1,k}+(s_i-a_{i,col})\times f_{i-1,j,k-1}$$

Then, for an illegal column \ (col \), its scheme number is \ (\ sum \ limits {UJ > k} f {n, J, K} \)

Next, consider how to calculate the total number of schemes

Let \ (g_{i,j} \) mean that considering the number of schemes in row \ (j \) is selected in column \ (I \), the transfer is simpler

$$g_{i,j}=g_{i-1,j}+s_i\times g_{i-1,j-1}$$

The total number of schemes is \ (\ sum \ limits {UJ = 1} ^ {n}g {n, J} \)

In this case, the complexity is \ (O(n^3m) \), the expected score is \ (84 \), and the enumeration times shall be optimized

It is found that it is meaningless to know the specific value of \ (j,k \) in \ (f_{i,j,k} \),

Then consider removing one dimension and changing it into \ (f_{i,j} \), which means that considering the \ (I \) row, the difference between the number of rows selected in the illegal column and the number of rows selected in other columns is \ (j \), that is, the original \ (j-k \)

In this way, the transfer becomes \ (O(n^2m) \) and the estimated score \ (100 \)

code
#include<cstdio>
#include<cstring>
#include<iostream>
#define LL long long
const int NN=105,MM=2005;
const LL mod=998244353;
namespace AE86{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
};
auto write=[](LL x,char opt='\n'){
char ch[20];short len=0;if(x<0)x=~x+1,putchar('-');
do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
for(short i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);
};
}using namespace AE86;
int n,m,a[NN][MM];
LL ans,s[NN],f[2][NN<<1],g[2][NN],tot,r[NN][MM];
namespace WSN{
inline short main(){
// freopen("meal.in","r",stdin);
// freopen("meal.out","w",stdout);
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j)
for(int j=1;j<=m;++j) r[i][j]=(s[i]-a[i][j]+mod)%mod;
}
for(int col=1;col<=m;++col){
memset(f,0,sizeof(f));f[0][n]=1;
for(int i=1;i<=n;++i)
for(int j=n-i;j<=n+i;++j)
f[i&1][j]=(f[(i-1)&1][j]+(j>0?f[(i-1)&1][j-1]*a[i][col]%mod:0)+(j<n*2?f[(i-1)&1][j+1]*r[i][col]%mod:0))%mod;
int tmp=0;
for(int j=1;j<=n;++j) tmp=(tmp+f[n&1][n+j])%mod;
ans=(ans+tmp)%mod;
}
g[0][0]=1;
for(int i=1;i<=n;++i)
for(int j=0;j<=n;++j)
g[i&1][j]=(g[(i-1)&1][j]+(j>0?s[i]*g[(i-1)&1][j-1]%mod:0))%mod;
for(int j=1;j<=n;++j) tot=(tot+g[n&1][j])%mod;
write((tot-ans+mod)%mod);
return 0;
}
}
signed main(){return WSN::main();}


$$tips$$:

Tolerance, exclusion, dynamic programming

## Gate of Babylon

More classic content exclusion topics, consider the transformation of topic meaning

There is an indefinite equation \ (x_1+x_2+...+x_n\leq m \), some of which \ (x_i \) are limited by \ (x_i\leq b_i \), and there are several nonnegative integer solutions of the legal indefinite equation.

Note: the following solutions are non negative integer solutions

First, consider how many solutions there are for the indefinite equation \ (x+y+z=10 \). It can be known that there are \ (C_12^2 \) solutions by the inserting plate method

Then it can be seen that there are \ (C {m + n-1} ^ {n-1} \) solutions to the indefinite equation \ (x_1+...+x_n=m \) with \ (n \) unknowns

Considering the solution of \ (x+y+z\leq 10 \), the board inserting method is also used to obtain \ (C_13^3 \), because a pile can be selected to free up space

Then there are \ (C {m + n} ^ {n} \) solutions of \ (x_1+...+x_n\leq m \) without restriction

Continue to consider the solution of \ (x+y+z\leq 10 \) with restrictions, assuming \ (x\leq 6 \)

This problem can be considered inclusive and exclusive. Subtracting the solution beyond the limit from the total solution is the limited solution. Consider calculating the solution beyond the limit

We can complete a new \ (xx=x+7 \), then for \ (x\leq 6 \), there are \ (XX < 0 \), that is, the number of solutions of \ (xx+7+y+z\leq 10 \) is \ (0 \),

Then, if you continue to use the board inserting method, the number of solutions exceeding the limit is \ (C_6^3 \), then the number of solutions of the last \ (x+y+z\leq 10 \) and \ (x\leq 6 \) is \ (C_13^3-C_6^3 \)

If there are multiple sets of restrictions in the topic, consider using tolerance and exclusion, odd subtraction and even addition, \ (2^T \) to enumerate all possible states, and then calculate the number of legal solutions

code
#include<cstdio>
#include<cstring>
#include<iostream>
#define int long long
const int NN=1e5+5;
using namespace std;
namespace AE86{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
};
auto write=[](int x,char opt='\n'){
char ch[20];short len=0;if(x<0)x=~x+1,putchar('-');
do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
for(short i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);
};
}using namespace AE86;
int n,m,t,mod,b[16],ans;
namespace Math{
int h[NN],v[NN];
auto qmo=[](int a,int b,int ans=1){
int c=mod;for(;b;b>>=1,a=a*a%c)if(b&1)ans=ans*a%c;
return ans;
};
auto inv=[](int x){return qmo(x,mod-2);};
auto prework=[](){
h[0]=h[1]=1; v[0]=v[1]=1;
for(int i=2;i<mod;++i) h[i]=h[i-1]*i%mod;
for(int i=2;i<mod;++i) v[i]=v[i-1]*inv(i)%mod;
};
auto C=[](int n,int m){return (n<m||n<0||m<0)?0:h[n]*v[n-m]%mod*v[m]%mod;};
inline int lucas(int n,int m){return m?lucas(n/mod,m/mod)*C(n%mod,m%mod)%mod:1;}
}using namespace Math;
namespace WSN{
inline short main(){
for(int i=0;i<(1<<t);i++){
int tmp=m,bs=(__builtin_popcount(i)&1)?-1:1;
for(int j=1;j<=t;j++)if(i&(1<<j-1))tmp-=(b[j]+1);
ans=(ans+bs*lucas(tmp+n,n)+mod)%mod;
}
write(ans);
return 0;
}
}
signed main(){return WSN::main();}


## Excalibar

Direct bipartite graph maximum weight independent set, just run network flow. As for why I look at others Detailed proof Yes, so if you want to know why, just turn right

Code (the most distinctive code among the three questions. Because the protagonist of the question is Dumbo, I still couldn't help but win the second prize)
#include<cstdio>
#include<cstring>
#include<iostream>
#define int long long
const int NN=5e5+5,inf=1e18;
using namespace std;
namespace Lancer{
auto Excalibar=[](){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
};
auto Enuma_Elish=[](int x,char opt='\n'){
char ch[20];short len=0;if(x<0)x=~x+1,putchar('-');
do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
for(short i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);
};
}using namespace Lancer;
int n,m,w[101][101],ans;
int dx[4]={0,0,-1,1},
dy[4]={-1,1,0,0};
};
namespace Archer{
int HD[NN],q[NN],h,t,dis[NN],S,T;
auto bfs=[](){
memset(dis,0x3f,sizeof(dis));
q[h=t=1]=S; dis[S]=0;
while(h<=t){
int x=q[h++];
if(dis[e[i].to]>dis[x]+1)
dis[e[i].to]=dis[x]+1,q[++t]=e[i].to;
if(x==T) return 1;
} return 0;
};
inline int dfs(int x,int in){
if(x==T) return in;
int rest=in,go;
int y=e[i].to,v=e[i].val;
if(dis[y]==dis[x]+1){
go=dfs(y,min(rest,v));
if(go) e[i].val-=go,e[i^1].val+=go,rest-=go;
else dis[y]=0;
}if(!rest) break;
} return in-rest;
}
auto dinic=[](int ans=0){
while(bfs()) ans+=dfs(S,inf);
return ans;
};
auto id=[](int x,int y){return (x-1)*m+y;};
}using namespace Archer;
namespace Saber{
inline short main(){
n=Excalibar(); m=Excalibar(); S=n*m+1; T=S+1;
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) w[i][j]=Excalibar(),ans+=w[i][j];
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
if((i+j)&1){
for(int k=0;k<4;k++){
int x=i+dx[k],y=j+dy[k];
if(x>0&&x<=n&&y>0&&y<=m)