题目链接:传送门
思路:
显然,al ^ ar < 2 * max{ al , ar };
又 sum(l+1,r-1) == al ^ ar < 2 * max{ al , ar } <= 2k+1 ; (k 是 max{ al , ar } 的最高位)
那么先枚举左端点 l , 计算 al 的最高位 k ,再枚举右端点 r ,对于满足 sum(l+1,r-1) < 2k+1 的 r 计算其是否满足sum(l+1,r-1) == al ^ ar ,否则break;
对于 任意 r ,最多被 最高位为k 的 左端点l 遍历到两次,如果超过两次了 显然最左边的 l 对应的 sum(l+1,r-1) > =2k+1 ,肯定提前就break了,那么复杂度就是 O(kn) , k大概为 log1e9.
代码:

1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 typedef unsigned long long uLL; 5 typedef pair<int,int> pii; 6 typedef pair<LL,LL> pLL; 7 typedef pair<double,double> pdd; 8 const int N=2e5+5; 9 const int M=1e7+5; 10 const int inf=0x3f3f3f3f; 11 const LL mod=998244353; 12 const double eps=1e-8; 13 const long double pi=acos(-1.0L); 14 #define ls (i<<1) 15 #define rs (i<<1|1) 16 #define fi first 17 #define se second 18 #define pb push_back 19 #define eb emplace_back 20 #define mk make_pair 21 #define mem(a,b) memset(a,b,sizeof(a)) 22 LL read() 23 { 24 LL x=0,t=1; 25 char ch; 26 while(!isdigit(ch=getchar())) if(ch=='-') t=-1; 27 while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); } 28 return x*t; 29 } 30 LL sum[N],a[N],n; 31 vector<pii> ans; 32 void cal(int t) 33 { 34 for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i]; 35 for(int l=1;l<n;l++) 36 { 37 int k; 38 for(k=30;k>=0&&((1<<k)&a[l])==0;k--) ; 39 LL lim=(1<<k+1); 40 for(int r=l+2;r<=n;r++) 41 { 42 LL x=sum[r-1]-sum[l]; 43 // printf("%lld %lld ",x,lim); 44 if(x>=lim) break; 45 if(x==(a[l]^a[r])){ 46 if(t==0) ans.eb(l,r); 47 else ans.eb(n-r+1,n-l+1); 48 } 49 } 50 } 51 } 52 int main() 53 { 54 n=read(); 55 for(int i=1;i<=n;i++) a[i]=read(); 56 cal(0); 57 reverse(a+1,a+n+1); 58 //for(int i=1;i<=n;i++) printf("%d ",a[i]); 59 cal(1); 60 sort(ans.begin(),ans.end()); 61 ans.erase(unique(ans.begin(),ans.end()),ans.end()); 62 //for(auto x:ans) printf("%d %d ",x.fi,x.se); 63 printf("%d ",ans.size()); 64 return 0; 65 }