cf 1438E. Yurii Can Do Everything(优美的暴力)
题目链接:传送门
思路:
定义sum(l,r)=Σri=lai;
显然,al ^ ar < 2 * max{ al , ar };
又 sum(l+1,r-1) == al ^ ar < 2 * max{ al , ar } <= 2k+1 ; (k 是 max{ al , ar } 的最高位)
那么先枚举左端点 l,&amp;nbsp;再枚举右端点 r,计算出k ,对于满足 sum(l+1,r-1) < 2k+1 的 r 计算其是否满足sum(l+1,r-1) == al ^ ar , 直到sum(l+1,r-1) ≥ 2k+1 break;
对于任意 r ,最多被最高位为k 的左端点l 遍历到两次;假设超过两次了,那么区间[l+1,r-1]至少会出现两个值 ≥ 2k ,sum(l+1,r-1) ≥ 2k+1与已知条件冲突。
总体复杂度就为O(kn)。
代码:
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 \n",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\n",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\n",x.fi,x.se); 63 printf("%d\n",ans.size()); 64 return 0; 65 }