折半搜索TLE求助
查看原帖
折半搜索TLE求助
443664
Missa楼主2022/3/5 13:23

rt,此题正解应该就是折半搜索吧。

或者有没有人指出代码或复杂度假了

复杂度上限 O(2n2(n2)2)O(2^{\frac{n}{2}}\cdot(\frac{n}{2})^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]);
} 
2022/3/5 13:23
加载中...