题意:
n个星球,每个星球有一个$p_i$,能从i走到j,当且仅当$p_i>p_j$,初始在1号星球,有能量$p_1$点,每到达i星球,能量变为$p^p_i$,问到达n星球最大能量是多少
$p_i<=3000,n<=1e5$
思路:
题目要求的即对于一些可选的j,$p_1>p_j>p_n$,这些$p_j$和$p_1^p_n$的异或和最大是多少
我们只需要标记一下能产生的异或和即可,最后选一个最大的
然后有种情况:当出现x,y,$x!=y,p_x==p_y$同时被选中的时候怎么办,(实际上x,y不能出现在一条路径中)
当x,y同时加入到路径中时,他们的异或和为0,相当于不在路径中,所以对结果没有影响
代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<string> #include<stack> #include<queue> #include<deque> #include<set> #include<vector> #include<map> #include<functional> #define fst first #define sc second #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define lc root<<1 #define rc root<<1|1 #define lowbit(x) ((x)&(-x)) using namespace std; typedef double db; typedef long double ldb; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> PI; typedef pair<ll,ll> PLL; const db eps = 1e-6; const int mod = 1e9+7; const int maxn = 2e6+100; const int maxm = 2e6+100; const int inf = 0x3f3f3f3f; const db pi = acos(-1.0); int p[maxn]; int n; int vis[maxn]; int main(){ mem(vis,0); scanf("%d", &n); for(int i = 1; i <= n; i++){ scanf("%d", &p[i]); } vis[p[1]^p[n]]=1; if(p[1]<=p[n])return printf("-1"),0; for(int i = 2; i < n; i++){ if(p[i]<p[1] && p[i]>p[n]){ for(int j = 0; j < (1<<13); j++){ vis[j] |= vis[j^p[i]]; } } } int ans = -1; for(int i = (1<<13);i >= 0; i--){ //printf("%d\n",i); if(vis[i]){ans = i;break;} } printf("%d", ans); return 0; }