大概就是让左边的x和y升序,右边的降序
#include<bits/stdc++.h>
#define int long long
#define ll long long
#define pb push_back
#define pii pair<ll,ll>
#define mp make_pair
#define fi first
#define se second
using namespace std;
template <class T> inline T read(){
T r=0,f=0;char c=getchar();
while(!isdigit(c)) f|=c=='-',c=getchar();
while(isdigit(c)) r=(r<<3)+(r<<1)+(c^48),c=getchar();
return f?-r:r;
}
const int _=45;
int n,xg,yg,way[_][2];
struct WATS2{ll x,y,cnt;};
map<pii,ll> p1[_],p2[_];
vector<WATS2> up1[_],up2[_];
bool cmp1(WATS2 x,WATS2 y){return x.x==y.x?x.y<y.y:x.x<y.x;}
bool cmp2(WATS2 x,WATS2 y){return x.x==y.x?x.y>y.y:x.x>y.x;}
void dfs(int x,int ed,int cnt,ll dx,ll dy,map<pii,ll> *S){
if(x>ed){++S[cnt][mp(dx,dy)];return;}
dfs(x+1,ed,cnt,dx,dy,S);
dfs(x+1,ed,cnt+1,dx+way[x][0],dy+way[x][1],S);
}
signed main(){
n=read<int>(),xg=read<int>(),yg=read<int>();
for(int i=1;i<=n;++i) way[i][0]=read<int>(),way[i][1]=read<int>();
dfs(1,n/2,0,0,0,p1),dfs(n/2+1,n,0,0,0,p2);
for(int i=0;i<=n;++i){
for(auto x:p1[i]) up1[i].pb({x.fi.fi,x.fi.se,x.se});
for(auto x:p2[i]) up2[i].pb({x.fi.fi,x.fi.se,x.se});
sort(up1[i].begin(),up1[i].end(),cmp1),sort(up2[i].begin(),up2[i].end(),cmp2);
}
for(int k=1;k<=n;++k){
ll ans=0;
for(int a=0;a<=k;++a){
int j=0;
for(auto x:up1[a]){
while(j<up2[k-a].size()&&up2[k-a][j].x+x.x>xg) ++j;
if(j==up2[k-a].size()||up2[k-a][j].x+x.x!=xg) continue;
while(j<up2[k-a].size()&&up2[k-a][j].y+x.y>yg) ++j;
if(j==up2[k-a].size()||up2[k-a][j].y+x.y!=yg) continue;
ans+=x.cnt*up2[k-a][j].cnt; ++j;
}
}
printf("%lld\n",ans);
}
return 0;
}