牛客挑战赛47 D Lots of Edges
思路:点的权值最多只有(1<<17)-1(131071) ,那我们可以枚举终点的值来算最短路,每个点能连边的值都是固定的,可以通过递归枚举子集(技巧)来找,每个点最多入队一次,所以最多只有131071次,枚举时会按位遍历 还有*17;
#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <cstdlib>
#define INF 0x3f3f3f3f3f3f3f3f
#define inf 0x3f3f3f3f
#define FILL(a,b) (memset(a,b,sizeof(a)))
#define re register
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(a) ((a)&-(a))
#define ios std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
#define fi first
#define rep(i,n) for(int i=0;(i)<(n);i++)
#define rep1(i,n) for(int i=1;(i)<=(n);i++)
#define se second
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define ac cout<<ans<<"\n"
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pii;
int dx[4]= {-1,1,0,0},dy[4]= {0,0,1,-1};
const ll mod=1e9+7;
const ll N =1e6+10;
const double eps = 1e-4;
//const double pi=acos(-1);
ll gcd(ll a,ll b){return !b?a:gcd(b,a%b);}
int a[N];
int n,s;
int d[N];
int b[N],q[N];
int tt=1,hh=0;
void dfs(int k,int y){if(d[k]!=inf&&d[k]!=0) return;d[k]=y;if(b[k]) q[++tt]=k;for(int i=k;i;i-=lowbit(i)) dfs(k^lowbit(i),y);
}
void sovle(){FILL(d,0x3f);cin>>n>>s;for(int i=1;i<=n;i++){cin>>a[i];b[a[i]]=1;}int t=(1<<17)-1;//cout<<t<<endl;q[1]=a[s];d[a[s]]=0;while(hh<tt){//cout<<hh<<" "<<tt<<endl;int k=q[++hh];dfs(k^t,d[k]+1);}for(int i=1;i<=n;i++){if(i==s) cout<<0<<" ";else if(d[a[i]]==inf) cout<<-1<<' ';else cout<<d[a[i]]<<" ";}
}
int main()
{iosint t=1;// cin>>t;while(t--){sovle();}return 0;
}