【洛谷P4144】大河的序列
阿新 • • 發佈:2019-04-09
二進制 兩個 con 尋找 題目 b- inf getchar end
題目大意:給定一個長度為 N 的序列,求序列中連續區間最大的(或和加與和)是多少。
題解:
引理:任意兩個數 \(i, j\),若 \(i>j\),則在二進制表示下,i 對應的二進制串的字典序一定大於 j 對應的二進制串的字典序。
根據引理,若當前的最優解為 X,現考慮新加入一個元素 Y,有以下三種情況。
- 若 \(X>Y\),則 Y 不應加入 X 對答案的貢獻中,因為對於或來說新加入 Y 的貢獻會比 Y & X 對答案的負貢獻小。
- 若 \(X=Y\),則無所謂。
- 若 \(X<Y\),不妨將 Y 設為當前最優解,結果會變得更優。
綜上,答案為序列中元素最大值的二倍。
二進制的最優解問題是具有貪心性質的,即:一個高位的 1 比所有低位均為 1 還要大。因此,只需每次盡量使得高位為 1 即可取得最優解。
另一種解法是 貪心+二分,枚舉左端點,再根據二進制位從高到低進行貪心,用二分加速尋找最優的右端點。時間復雜度為 \(O(nlog^2n)\)。
代碼如下
#include <bits/stdc++.h> #define fi first #define se second #define pb push_back #define mp make_pair #define all(x) x.begin(),x.end() #define cls(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long ll; typedef pair<int,int> P; const int dx[]={0,1,0,-1}; const int dy[]={1,0,-1,0}; const int mod=1e9+7; const int inf=0x3f3f3f3f; const int maxn=1e5+10; const double eps=1e-6; inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline ll sqr(ll x){return x*x;} inline ll fpow(ll a,ll b,ll c){ll ret=1%c;for(;b;b>>=1,a=a*a%c)if(b&1)ret=ret*a%c;return ret;} inline ll read(){ ll x=0,f=1;char ch; do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch)); do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch)); return f*x; } /*------------------------------------------------------------*/ ll n,b,p,a[maxn],sum[32][maxn]; void read_and_parse(){ n=read(),b=read(),p=read(); for(int i=1;i<=n;i++)a[i]=read(); for(int i=0;i<=25;i++) for(int j=1;j<=n;j++) sum[i][j]=sum[i][j-1]+(a[j]>>i&1); } void solve(){ ll ans=0; for(int i=1;i<=n;i++){ ll lb=i,rb=n,ret=0; for(int bit=25;~bit;bit--){ if(a[i]>>bit&1){ ll l=lb-1,r=rb; while(l<r){ int mid=l+r+1>>1; if(sum[bit][mid]-sum[bit][i-1]==mid-i+1)l=mid; else r=mid-1; } if(l==lb-1)ret+=(1<<bit); else ret+=2*(1<<bit),rb=l; }else{ ll l=lb,r=rb+1; while(l<r){ int mid=l+r>>1; if(sum[bit][mid]-sum[bit][i-1]>0)r=mid; else l=mid+1; } if(r==rb+1)continue; else ret+=(1<<bit),lb=r; } } ans=max(ans,ret); } printf("%lld\n",fpow(ans+233,b,p)); } int main(){ read_and_parse(); solve(); return 0; }
【洛谷P4144】大河的序列