rt,此题正解应该就是折半搜索吧。
或者有没有人指出代码或复杂度假了
复杂度上限 O(22n⋅(2n)2)
#include <cstdio>
#include <map>
#define LL long long
using namespace std;
const int M = 45;
int n, xx, yy, x[M], y[M], k, ans[M];
struct dat {LL x, y; bool operator < (dat t) const{
return x ^ t.x ? x < t.x : y < t.y;
}};
map<dat, int> m1[M], m2[M];
LL sx, sy;
void dfs1(int t, int chs){
if(t == k+1) return;
dfs1(t+1, chs);
sx += 1ll * x[t]; sy += 1ll * y[t]; m1[chs+1][{sx, sy}]++;
dfs1(t+1, chs+1);
sx -= x[t]; sy -= y[t];
}
LL tx, ty;
void dfs2(int t, int chs){
if(t == n+1) return;
dfs2(t+1, chs);
tx += 1ll * x[t]; ty += 1ll * y[t]; m2[chs+1][{tx, ty}]++;
dfs2(t+1, chs+1);
tx -= x[t]; ty -= y[t];
}
int main(){
scanf("%d %d %d", &n, &xx, &yy); k = n >> 1;
for(int i = 1; i <= n; i++) scanf("%d %d", &x[i], &y[i]);
dfs1(1, 0); dfs2(k+1, 0);
for(int i = 1; i <= k; i++){
auto iter = m1[i].find({xx, yy});
if(iter != m1[i].end()) ans[i] += iter -> second;
}
for(int i = 1; i <= k+1; i++){
auto iter = m2[i].find({xx, yy});
if(iter != m2[i].end()) ans[i] += iter -> second;
}
for(int i = 1; i <= k; i++){
for(auto iter1 : m1[i]){
sx = iter1.first.x; sy = iter1.first.y;
for(int j = 1; j <= k+1; j++){
auto iter2 = m2[j].find({xx-sx, yy-sy});
if(iter2 != m2[j].end()){
ans[i+j] += iter1.second * iter2 -> second;
}
}
}
}
for(int i = 1; i <= n; i++)
printf("%d\n", ans[i]);
}