zoukankan      html  css  js  c++  java
  • [CSAcademy]Or Problem

    [CSAcademy]Or Problem

    题目大意:

    一个长度为(n(nle2 imes10^5))的序列(A(0le A_i<2^{20})),将其分为恰好(m)个连续段,设每一段的代价为这一段数字的或,总代价为每一段代价和。求最小代价和。

    思路:

    一个普通的DP思路是,对于每个数(A_i),枚举每一位,找到上一个在这一位上为(1)的数(A_k)(A_{k+1sim i})为最后一段。转移方程为(f[i][j]=max{f[k][j-1]+vee_{ell=k+1}^i A_{ell}})

    使用带权二分可以去掉(m)段的状态。

    源代码:

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<algorithm>
    inline int getint() {
    	register char ch;
    	while(!isdigit(ch=getchar()));
    	register int x=ch^'0';
    	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    	return x;
    }
    typedef long long int64;
    const int N=2e5+1,logN=18,logA=20;
    int n,st[N][logN],p[logA],g[N];
    int64 f[N];
    inline int lg2(const float &x) {
    	return ((unsigned&)x>>23&255)-127;
    }
    inline int calc(const int &l,const int &r) {
    	const int k=lg2(r-l+1);
    	return st[l][k]|st[r-(1<<k)+1][k];
    }
    inline void solve(const int &c) {
    	memset(p,0,sizeof p);
    	for(register int i=1;i<=n;i++) {
    		f[i]=calc(1,i)-c;
    		g[i]=0;
    		for(register int j=0;j<logA;j++) {
    			if(st[i][0]>>j&1) p[j]=i;
    			if(!p[j]) continue;
    			const int64 tmp=f[p[j]-1]+calc(p[j],i)-c;
    			if(f[i]<tmp) {
    				f[i]=tmp;
    				g[i]=0;
    			}
    			if(tmp==f[i]) g[i]=std::max(g[i],g[p[j]-1]+1);
    		}
    	}
    }
    int main() {
    	n=getint();
    	const int m=getint();
    	for(register int i=1;i<=n;i++) st[i][0]=getint();
    	for(register int j=1;j<logN;j++) {
    		for(register int i=1;i+(1<<(j-1))<=n;i++) {
    			st[i][j]=st[i][j-1]|st[i+(1<<(j-1))][j-1];
    		}
    	}
    	int l=0,r=1e9;
    	int64 ans=0;
    	while(l<=r) {
    		const int mid=(l+r)>>1;
    		solve(mid);
    		if(g[n]>=m) {
    			l=mid+1;
    			ans=f[n]+1ll*m*mid;
    		} else {
    			r=mid-1;
    		}
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    Vue基础
    ES6之promise
    第13次作业--邮箱的正则表达式
    第12次作业--你的生日
    第11次作业--字符串处理
    第10次作业
    Java找回感觉的练习
    第四次博客作业-结对项目
    第9次作业--接口及接口回调
    深入面向对象——继承
  • 原文地址:https://www.cnblogs.com/skylee03/p/10143780.html
Copyright © 2011-2022 走看看