topcoder 11478 MagicalGirlLevelThreeDivOne

给出 \(n\) 个字符串,编号为 \(0\)\(n-1\) . 从 \(n\) 个开始,编号为 \(i\) 的字符串 \(A_i=A_{i-1}+A_{i-1-k}+A_{i-1-2k}+\cdots\)

\(A_k\) 的子段 \([l,r]\) 中最多有多少个连续的 \(1\) .

\(1\leq n\leq 50,0\leq k\leq 10^9,0\leq l\leq r\leq 10^{15},\forall i\in[0,n-1], 1\leq |A_i|\leq 50\)

考虑 \(A_{i-1}\) 肯定是 \(A_i\) 的前缀,那么,对于 \(i<k\) , 如果 \(|A_i|>r\) ,那么,在 \(A_i\)\([l,r]\) 和在 \(A_k\)\([l,r]\) 是相同的 .

此时观察得到 \(A_i\) 的增长速度非常快,最多 \(600+\) 个字符串长度就能达到 \(10^{15}\) .

进一步发现,多少个连续的 \(1\) , 我只需要求出自称它的字符串中每一个的长度 \(sz\) , 前缀 \(0\) 个数 \(pr\) , 后缀 \(0\) 个数 \(bk\) ,最多连续的 \(1\) 的长度 \(mx\) . 然后 \(O(n)\) 地合并得到当前串的 \(sz,pr,bk,mx\) .

但是发现,字符串中不一定是求满的,即为,可能我会截取字符串中的一部分,为了好写,考虑 \(dp\) 状态为 \(dp(i,l,r)\)\(A_i\)\([l,r]\) 的结果,然后记忆化搜索.

\(i<n\)\(i\geq n\) 的两部分是要分开处理的 .

时间复杂度 : \(O(\omega n)\)

空间复杂度 : \(O(\omega)\)

其中 \(\omega\approx 2000\) .

code

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define pll pair<long long,long long>
#define fi first
#define se second
const int N=55;
class MagicalGirlLevelThreeDivOne{
public:
	int n,ID=-1;
	vector<string>s;
	long long len[N*N*N];
	class node{public:long long sz,mx,pr,bk;};
	map<pair<int,pll>,node>dp;
	node get_dp(int id,long long l,long long r){
		if(dp.find(mp(id,mp(l,r)))!=dp.end())return dp[mp(id,mp(l,r))];
		if(id<n){
			int sz=r-l+1,pr=0,bk=0,mx=0;
			for(int i=l;i<=r;i++){
				if(s[id][i]=='0')break;
				pr++;
			}
			for(int i=r;i>=l;i--){
				if(s[id][i]=='0')break;
				bk++;
			}
			int cnt=0;
			for(int i=l;i<=r;i++){
				cnt=s[id][i]=='1'?cnt+1:0;
				mx=max(mx,cnt);	
			}
			return dp[mp(id,mp(l,r))]=(node){sz,mx,pr,bk};
		}else{
			vector<int>v;
			for(int i=id-1;i>=0;i-=n)v.pb(i);
			vector<node>ve;
			long long tmp=0;
			for(auto nid:v){
				long long nl=max(tmp,l),nr=min(tmp+len[nid]-1,r);
				if(nl>nr){
					tmp+=len[nid];
					continue;
				}
				ve.pb(get_dp(nid,nl-tmp,nr-tmp));
				tmp+=len[nid];	
			}
			long long mx=0,pr=0,bk=0,sz=r-l+1;
			for(auto nw:ve){
				pr+=nw.pr;
				if(nw.pr!=nw.sz)break;
			}
			for(int i=(int)ve.size()-1;i>=0;i--){
				node nw=ve[i];
				bk+=nw.bk;
				if(nw.bk!=nw.sz)break;
			}
			long long cnt=0;
			for(auto nw:ve){
				mx=max(max(cnt+nw.pr,nw.mx),mx);
				cnt=nw.bk==nw.sz?cnt+nw.sz:nw.bk;
			}
			mx=max(mx,cnt);
			return dp[mp(id,mp(l,r))]=(node){sz,mx,pr,bk};
		}
	}
	long long theMaxPower(vector<string>F,int N,long long lo,long long hi){
		n=(int)F.size();int k=N;
		for(int i=0;i<n;i++)s.pb(F[i]),len[i]=(int)s[i].size();
		for(int i=n;;i++){
			for(int j=i-1;j>=0;j-=n)len[i]+=len[j];
			if(len[i]>hi){
				ID=i;
				break;
			}
		}
		ID=min(ID,k);
		node ans=get_dp(ID,lo,hi);
		return ans.mx;
	}
}test;
posted @ 2022-02-03 10:05  xyangh  阅读(23)  评论(0)    收藏  举报