社区讨论
再求卡常(玄关)
P14638[NOIP2025] 序列询问参与者 4已保存回复 5
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 5 条
- 当前快照
- 1 份
- 快照标识符
- @misvv8hm
- 此快照首次捕获于
- 2025/12/05 21:11 2 个月前
- 此快照最后确认于
- 2025/12/07 15:25 2 个月前
rt,之前有一位大佬已经给我卡过了,但是正式数据过不了。
CPP#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define FOR(i,a,b) for(int i=(a),E##i=(b);i<=E##i;i++)
#define REV(i,a,b) for(int i=(a),E##i=(b);i>=E##i;i--)
#define CLOSE_TIE ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define psbk push_back
#define endl '\n'
template <typename T>
void _outval(string s,int p,const T &t) {cout<<s.substr(p,s.length()-p)<<'='<<t<<endl; }
template <typename T, typename... Args>
void _outval(string s,int p,const T &t,const Args &...rest){
string n="";
while(s[p]!=',') n+=s[p++];
cout<<n<<'='<<t<<", ";
_outval(s,p+1,rest...);
}
#define outval(...) _outval(#__VA_ARGS__,0,__VA_ARGS__)
#define outarr(a,be,ed)\
{cout<<(#a)<<": ";\
FOR(iiii,be,ed)cout<<'['<<iiii<<"]="<<a[iiii]<<(iiii<ed?", ":"\n");}
#ifdef __linux__
#define gc getchar_unlocked
#define pc putchar_unlocked
#else
#define gc _getchar_nolock
#define pc _putchar_nolock
#endif
template<typename Tp> inline void read(Tp &x) {x=0; register bool z=true; register char a=gc(); for(;!isdigit(a);a=gc()) if(a=='-') z=false; for(;isdigit(a);a=gc()) x=(x<<1)+(x<<3)+(a^48); x=(z?x:~x+1);}
template<typename T,typename ...Tp> inline void read(T &x,Tp &...y) {read(x),read(y...);}
template<typename Tp> inline void write(Tp x) {if(!x) return pc(48),void(); if(x<0) pc('-'),x=~x+1; register int len=0; register char tmp[64]; for(;x;x/=10) tmp[++len]=x%10+48; while(len) pc(tmp[len--]);}
const int N=5e4+5;
const int lgN=20;
const ll INF=1e15;
int n,lgn,Q,L,R,lg[N];
ll a[N],sum[N],ans[N],f[N],g[N],b[lgN][N],q[N];
struct ST{
ll mx[lgN][N],mn[lgN][N];
void init(int n,ll a[]){
FOR(i,0,n) mx[0][i]=mn[0][i]=a[i];
FOR(i,1,lg[n])
FOR(j,0,n-(1<<i)+1){
mx[i][j]=max(mx[i-1][j],mx[i-1][j+(1<<(i-1))]);
mn[i][j]=min(mn[i-1][j],mn[i-1][j+(1<<(i-1))]);
}
}
ll queryMax(int l,int r){
int lgl=lg[r-l+1];
return max(mx[lgl][l],mx[lgl][r-(1<<lgl)+1]);
}
ll queryMin(int l,int r){
int len=r-l+1,lgl=lg[len];
return min(mn[lgl][l],mn[lgl][r-(1<<lgl)+1]);
}
}st;
struct SmallST{
ll mx[5][lgN];
void init(int n,int k){
FOR(i,0,n) mx[0][i]=b[i][k];
FOR(i,1,lg[n])
FOR(j,0,n-(1<<i)+1)
mx[i][j]=max(mx[i-1][j],mx[i-1][j+(1<<(i-1))]);
}
ll queryMax(int l,int r){
int lgl=lg[r-l+1];
return max(mx[lgl][l],mx[lgl][r-(1<<lgl)+1]);
}
}stSml[N];
inline void solve(int l,int r){
if(r-l+1<L) return;
if(l==r){
if(L==1) ans[l]=max(ans[l],a[l]);
return;
}
int mid=(l+r)>>1,le=min(n,l+L-2),ri=min(n,l+R-2);
ll now=-INF;
FOR(i,l,mid){
if(i+L-1<=n){
if(le<n) ++le;
if(ri<n) ++ri;
int ll=max(le,mid+1),rr=min(ri,r);
if(ll<=rr) now=max(now,st.queryMax(ll,rr)-sum[i-1]);
}
ans[i]=max(ans[i],now);
}
now=-INF,le=max(r-R+2,1),ri=max(r-L+2,1);
REV(i,r,mid+1){
if(i-L+1>=1){
if(le>1) --le;
if(ri>1) --ri;
int ll=max(le,l)-1,rr=min(ri,mid)-1;
if(ll<=rr) now=max(now,sum[i]-st.queryMin(ll,rr));
}
ans[i]=max(ans[i],now);
}
solve(l,mid),solve(mid+1,r);
}
inline void small(int L,int R){
int ri=R-1;
FOR(i,1,n){
if(ri<n) ++ri;
f[i]=(i+L-1<=n?st.queryMax(i+L-1,ri)-sum[i-1]:-INF);
g[i]=(i-L+1>0?sum[i]-st.queryMin(max(i-R+1,1)-1,i-L):-INF);
}
int hdf=0,tlf=-1,hdg=0,tlg=-1;
FOR(i,1,n){
while(hdf<=tlf&&q[hdf]<i-L+1) ++hdf;
while(hdf<=tlf&&f[q[tlf]]<f[i]) --tlf;
q[++tlf]=i;
ans[i]=max(ans[i],f[q[hdf]]);
}
REV(i,n,1){
while(hdg<=tlg&&q[hdg]>i+L-1) ++hdg;
while(hdg<=tlg&&g[q[tlg]]<g[i]) --tlg;
q[++tlg]=i;
ans[i]=max(ans[i],g[q[hdg]]);
}
}
map<pair<int,int>,ull>mp;
signed main(){
CLOSE_TIE
read(n);
lg[0]=-1;
FOR(i,1,n){
lg[i]=lg[i>>1]+1;
read(a[i]);
sum[i]=sum[i-1]+a[i];
}
lg[n+1]=lg[(n+1)>>1]+1; lgn=lg[n];
st.init(n+1,sum);
FOR(i,1,n) b[0][i]=a[i];
FOR(k,1,lgn){
L=(1<<k),R=(1<<(k+1))-1;
FOR(i,1,n) ans[i]=-INF;
solve(1,n);
FOR(i,1,n) b[k][i]=ans[i];
}
FOR(i,1,n) stSml[i].init(lgn+1,i);
read(Q);
while(Q--){
read(L,R); if(mp.count({L,R})){cout<<mp[{L,R}]<<"\n"; continue;}
ull ANS=0;
int lgL=lg[L],lgR=lg[R];
FOR(i,1,n) ans[i]=(lgL+1<=lgR-1?stSml[i].queryMax(lgL+1,lgR-1):-INF);
if(lgL==lgR) small(L,R);
else small(L,(1<<(lgL+1))-1),small((1<<lgR),R);
FOR(i,1,n) ANS^=(ull)i*ans[i];
cout<<ANS<<"\n";
}
return 0;
}
回复
共 5 条回复,欢迎继续交流。
正在加载回复...