zoukankan      html  css  js  c++  java
  • Codeforces 1208F

    题面传送门

    题意:求 (maxlimits_{i<j<k}a_i|(a_j&a_k))
    (1leq n leq 10^6,1leq a_ileq 2 imes 10^6)

    u1s1 这题算高维前缀和里不那么 sb 的题,虽然代码也很简单。
    很容易想到一个贪心,从高到低枚举每一位,能填 (1) 就填 (1),不能填 (1) 就填 (0)
    于是本题转化为一个问题:是否存在某个 (i,j,k) 使得 (x)(a_i|(a_j&a_k)) 的子集。枚举 (a_i) 包含 (x) 中的哪些位,然后贪心地取下标最小的 (i),以及下标最大的 (j,k),判断 (i<j) 即可。
    至于怎样求下标最小的 (i) 和下标最大的 (j,k)。记 (mn_x) 为下标最小的包含 (x)(a_i)(mx_x) 为下标最大的两个包含 (x)(a_i)。高位前缀和随便一搞就行了。

    #include <bits/stdc++.h>
    using namespace std;
    #define fi first
    #define se second
    #define fz(i,a,b) for(int i=a;i<=b;i++)
    #define fd(i,a,b) for(int i=a;i>=b;i--)
    #define ffe(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
    #define fill0(a) memset(a,0,sizeof(a))
    #define fill1(a) memset(a,-1,sizeof(a))
    #define fillbig(a) memset(a,63,sizeof(a))
    #define pb push_back
    #define ppb pop_back
    #define mp make_pair
    template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
    template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
    typedef pair<int,int> pii;
    typedef long long ll;
    template<typename T> void read(T &x){
    	x=0;char c=getchar();T neg=1;
    	while(!isdigit(c)){if(c=='-') neg=-1;c=getchar();}
    	while(isdigit(c)) x=x*10+c-'0',c=getchar();
    	x*=neg;
    }
    const int MAXN=1e6;
    const int LOG_N=21;
    const int LIM=(1<<LOG_N)-1;
    int n,a[MAXN+5],tmp[4],mn[LIM+5];
    pii mx[LIM+5];
    pii merge(pii x,pii y){
    	tmp[0]=x.fi,tmp[1]=x.se,tmp[2]=y.fi,tmp[3]=y.se;
    	sort(tmp,tmp+4);reverse(tmp,tmp+4);return mp(tmp[0],tmp[1]);
    }
    bool check(int x){
    	for(int i=x;i;i=(i-1)&x) if(mn[x^i]<mx[i].se) return 1;
    	return (mn[x]<mx[0].se);
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    	memset(mn,63,sizeof(mn));
    	for(int i=1;i<=n;i++) mn[a[i]]=min(mn[a[i]],i);
    	for(int i=1;i<=n;i++) mx[a[i]]=merge(mx[a[i]],mp(i,0));
    	for(int i=0;i<LOG_N;i++) for(int j=LIM;~j;j--) if(!(j>>i&1)){
    		mn[j]=min(mn[j],mn[j^(1<<i)]);mx[j]=merge(mx[j],mx[j^(1<<i)]);
    	}
    	int cur=0;for(int i=LOG_N;~i;i--) if(check(cur|(1<<i))) cur|=(1<<i);
    	printf("%d
    ",cur);
    	return 0;
    }
    

    上帝不要惩罚我刷水题(

  • 相关阅读:
    JVM字节码(七)
    JVM字节码(六)
    JVM字节码(五)
    JVM字节码(四)
    JVM字节码(三)
    JVM字节码(二)
    JVM字节码(一)
    JVM类加载器(五)
    JVM类加载器(四)
    php之 人员的权限管理
  • 原文地址:https://www.cnblogs.com/ET2006/p/Codeforces-1208F.html
Copyright © 2011-2022 走看看