update pdf perfect

This commit is contained in:
Zengtudor 2024-08-09 23:03:07 +08:00
parent a836526826
commit 0b26230ebd
3 changed files with 120 additions and 50 deletions

View File

@ -1,63 +1,67 @@
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define AS(c){if(!(c)){cout<<"assert failed: "<<#c<<endl;}}
const int MAX_N=5e5+5;
const int MAX_K=50;
int n,k,ans{0};
int smin[MAX_N][MAX_K],smax[MAX_N][MAX_K],l[MAX_N];
const int MAX_N = 3e5+5;
int a[MAX_N],tmax[MAX_N*4],tmin[MAX_N*4];
int n;
int ans=INT_MIN;
int read();
int pow2(int n){return 1<<n;}
void build(int tmin[],int tmax[],int a[],int s,int e,int n){
if(s==e){
tmax[n]=tmin[n]=a[s];
return;
}
int m=s+(e-s)/2;
build(tmin, tmax, a, s, m, n*2);
build(tmin, tmax, a, m+1, e, n*2+1);
tmax[n]=max(tmax[n*2],tmax[n*2+1]);
tmin[n]=min(tmin[n*2],tmin[n*2+1]);
}
int search_max(int tmax[],int s,int e,int n,int l,int r){
if(l<=s&&e<=r)return tmax[n];
if(e<l||r<s)return LONG_LONG_MIN;
int m=s+(e-s)/2;
int nmax=LONG_LONG_MIN;
if(l<=m)nmax=max(search_max(tmax, s, m, n*2, l, r),nmax);
if(m<r)nmax=max(search_max(tmax, n+1, e, n*2+1, l, r),nmax);
return nmax;
}
int search_min(int tmin[],int s,int e,int n,int l,int r){
if(l<=s&&e<=r)return tmin[n];
if(e<l||r<s)return LONG_LONG_MAX;
int m=s+(e-2)/2;
int nmin=LONG_LONG_MAX;
if(l<=m)nmin=min(search_max(tmax, s, m, n*2, l, r),nmin);
if(m<r)nmin=min(search_max(tmax, m+1, e, n*2+1, l, r),nmin);
return nmin;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
signed main(signed argc,char *argv[]){
#ifdef OITEST
cout<<"TESTING"<<endl;
AS(argc==3)
auto f = freopen(argv[1],"r",stdin);
AS(f!=NULL)
ifstream afile(argv[2]);
AS(afile.is_open()==true)
int cans;
afile>>cans;
#endif
n=read();
// if(n>999){cout<<1048575<<endl;return 0;}
l[1]=0;
for(int i=1;i<=n;i++){
cin>>a[i];
if(i>1)l[i]=l[i/2]+1;
smin[i][0]=smax[i][0]=read();
}
build(tmin, tmax, a, 1, n, 1);
for(int l=1;l<=n;l++){
for(int r=l;r<=n;r++){
k=l[n]+1;
for(int j=1;j<=k;j++){
for(int i=1;i+(1<<j)-1<=n;i++){
smin[i][j]=min(smin[i][j-1],smin[i+pow2(j-1)][j-1]);
smax[i][j]=max(smax[i][j-1],smax[i+pow2(j-1)][j-1]);
}
}
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){
int k=l[j-i+1];
ans=max(
search_max(tmax, 1, n, 1, l, r)
^
search_min(tmin, 1, n, 1, l, r)
,
ans
ans,
(min(smin[i][k],smin[j-(pow2(k)+1)][k])
^
max(smax[i][k],smax[j-pow2(k)+1][k]))
);
}
}
cout<<ans<<endl;
#ifdef OITEST
AS(ans==cans)
#endif
}
int read(){
int x=0,w=1;
char ch=0;
while(!isdigit(ch)){
if(ch=='-')w=-1;
ch=getchar();
}
while(isdigit(ch)){
x=x*10+ch-'0';
ch=getchar();
}
return x*w;
}

66
day5/perfect/perfect.md Normal file
View File

@ -0,0 +1,66 @@
# 完美的答卷
## 题目背景
$F$ 还是退役了,成为了超级银牌王。
也许多年以后他会忘掉排名,忘掉题目,忘掉 $OI$,甚至忘掉 $A+B$ 怎么写。
但他永不会忘记那些热血沸腾、激动人心的瞬间。
这份 绝对的炽热,为他的 $OI$ 生涯交出了完美的答卷。
## 题目描述
$F$ 的生涯一共可以分成 $n$ 个阶段,每个阶段有一个实力值 $a_i$ , 保证实力值之间互不相同。
$F$ 用一种奇怪的方式给他的每个生涯区间打了分。
对于 $1 ≤ l ≤ r ≤ n$,生涯区间 $[l, r]$ 的分数 $f (l, r) = \max\limits_{i=l}^{r} {a_i } ⊕ \min\limits_{i=l}^{r} {a_i } $,其中 $⊕$ 表示按位异或。
$F$ 想知道所有生涯区间的分数的最大值,也就是 $\max\limits_{1≤l≤r≤n} {f (l, r)}$。
这是他生涯中最后的愿望了。
## 输入格式
第一行一个正整数 $n$,表示阶段数量。
第二行 $n$ 个非负整数,第 $i$ 个整数 $a_i$ 表示第 $i$ 个阶段的实力值。
## 输出格式
一个整数表示答案。
## 样例 #1
### 样例输入 #1
```
5
2 1 5 3 4
```
### 样例输出 #1
```
7
```
## 提示
对于 $100\%$ 的数据,$1 ≤ n ≤ 3 × 10^5 , 0 ≤ a_i ≤ 10^6$,保证 $a_i$ 互不相同。
|子任务|$n≤$|特殊性质|得分|
| :--------: | :-----------: | :-----------: | :-----------: |
|1|$500$|无|$12$|
|2|$5000$|无|$16$|
|3|$3 × 10^5$|$A$|$8$|
|4|$3 × 10^5$|$B$|$16$|
|5|$3 × 10^5$|$C$|$20$|
|6|$3 × 10^5$|无|$28$|
特殊性质 $A$:保证对于所有 $1 ≤ i < n$, $a_i < a_{i+1}$
特殊性质 $B$:保证对于所有 $1 ≤ i < n$, $a_i \& a_{i+1} = 0$,其中 $\&$ 表示按位与
特殊性质 $C$:保证数据随机。

BIN
day5/perfect/perfect.pdf Normal file

Binary file not shown.