链接:https://ac.nowcoder.com/acm/contest/317/C
来源:牛客网
小a正在玩一款星际探索游戏,小a需要驾驶着飞船从
11号星球出发前往nn号星球。其中每个星球有一个能量指数pp。星球ii能到达星球jj当且仅当pi>pjpi>pj。
同时小a的飞船还有一个耐久度tt,初始时为11号点的能量指数,若小a前往星球jj,那么飞船的耐久度会变为t⊕pjt⊕pj(即tt异或pjpj,关于其定义请自行百度)
小a想知道到达nn号星球时耐久度最大为多少
同时小a的飞船还有一个耐久度tt,初始时为11号点的能量指数,若小a前往星球jj,那么飞船的耐久度会变为t⊕pjt⊕pj(即tt异或pjpj,关于其定义请自行百度)
小a想知道到达nn号星球时耐久度最大为多少
注意:对于每个位置来说,从它出发可以到达的位置仅与两者的
pp有关,与下标无关
输入描述:
第一行一个整数nn,表示星球数
接下来一行有nn个整数,第ii个整数表示pipi
输出描述:
一个整数表示到达nn号星球时最大的耐久度
若不能到达nn号星球或到达时的最大耐久度为00则输出−1−1
示例1
备注:
1⩽n,∀pi⩽3000
这题很明显线性基,但是一开始做的时候没有看到 pi 必须大于 pj 这条限制条件 就直接打了,打完发现样例不过,自己也看不懂样例。
重新读了一遍题才发现那个条件,果然电子竞技不需要视力。
只需要把P0作为最大值 Pn-1作为最小值,处理出来新的数组,然后再线性基最大值就行了。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; int arr[3005]; int stu[3005]; int p[15]; int main(){ int n; int cnt=0; int ans; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&arr[i]); } if(arr[0]<=arr[n-1]){ puts("-1"); return 0; } ans = arr[0]^arr[n-1]; for(int i=1;i<n-1;i++){ if(arr[n-1] < arr[i] && arr[i] < arr[0]) stu[cnt++] = arr[i]; } memset(p,0,sizeof(p)); for(int i=0;i<cnt;i++){ for(int j=11;j>=0;j--){ if(stu[i]>>j&1){ if(p[j]){ stu[i] ^= p[j]; }else { p[j] = stu[i]; break; } } } } for(int i=0;i<12;i++){ for(int j=i+1;j<12;j++){ if(p[j]>>i&1)p[j]^=p[i]; } } for(int i=0;i<12;i++){ if(ans < (ans ^ p[i])) ans ^= p[i]; } printf("%d\n",ans); return 0; }