首页 > 其他分享 >「JOI 2018 Final」毒蛇越狱

「JOI 2018 Final」毒蛇越狱

时间:2024-12-26 17:21:56浏览次数:1  
标签:cnt le int 复杂度 id step 2018 JOI Final

好题。

题意

给你 \(0\sim 2^k-1\) 这 \(2^k\) 个数,第 \(i\) 个数的权值是 \(a_i\)。有 \(q\) 次询问,每次询问给出一个由 0,1,? 组成的字符串,你需要把 ? 替换成 0,1,替换后把该串视为一个二进制数 \(x\),求所有可能的 \(x\) 的权值和。

\(k\le 20,q\le 10^6\)

分析

有一个非常显然的暴力就是爆搜所有 ? 填什么,时间复杂度 \(O(q2^{cnt_?})\)。

但是肯定过不去。

注意到 \(\min(cnt_0,cnt_1,cnt_?)\le \frac{n}{3}=6\),启发我们思考能不能在 01 上搞事情。

假设 \(cnt_1\le 6\),发现难点在于 1 这些位只能取 1 而不像 ? 可以任取,如果没有 1 那么直接高维前缀和就行。结合给的条件,考虑容斥,钦定某些 1 错填 0,其他 1 视为 ? 一样填,容斥系数即是 \((-1)^{错填成0的1数量}\),时间复杂度 \(O(q2^{cnt_1})\)。

当 \(cnt_0\le 6\) 时,做法和 \(cnt_1\le 6\) 没啥太大的不一样,但是注意要做的变成了高维后缀和。

当 \(cnt_?\le 6\) 时套用朴素爆搜。

时间复杂度 \(O(q2^{\frac{n}{3}})\)。代码非常好写。

const int maxn=21,maxm=1<<20,inf=0x3f3f3f3f;
const long long llinf=0x3f3f3f3f3f3f3f3f;
int k,Q,n;
int a[maxm];
char s[maxn];
int f[maxm],g[maxm];
vector<int>v0,v1,v2;
inline int dfs2(int step,int id){
	if(step==(int)v2.size())return a[id];
	return dfs2(step+1,id)+dfs2(step+1,id|(1<<v2[step]));
}
inline int dfs0(int step,int id,int fir){
	if(step==(int)v0.size())return fir*g[id];
	return dfs0(step+1,id,fir)+dfs0(step+1,id|(1<<v0[step]),-fir);
}
inline int dfs1(int step,int id,int fir){
	if(step==(int)v1.size())return fir*f[id];
	return dfs1(step+1,id,-fir)+dfs1(step+1,id|(1<<v1[step]),fir);
}
inline void solve_the_problem(){
	k=rd(),Q=rd(),n=1<<k;
	rep(i,0,n-1)scanf("%1d",&a[i]);
	rep(i,0,n-1)f[i]=g[i]=a[i];
	rep(i,1,k){
		rep(S,0,n-1){
			if((S>>(i-1))&1)f[S]+=f[S^(1<<(i-1))];
			else g[S]+=g[S^(1<<(i-1))];
		}
	}
	while(Q--){
		scanf("%s",s+1);
		v0.clear(),v1.clear(),v2.clear(); 
		rep(i,1,k){
			if(s[i]=='0')v0.pb(k-i);
			if(s[i]=='1')v1.pb(k-i);
			if(s[i]=='?')v2.pb(k-i);
		}
		if(v2.size()<=6){
			int S=0;
			rep(i,1,k)if(s[i]=='1')S|=(1<<(k-i));
			write(dfs2(0,S));
		}else if(v0.size()<=6){
			int S=0;
			rep(i,1,k)if(s[i]=='1')S|=(1<<(k-i));
			write(dfs0(0,S,1));
		}else{
			int S=0;
			rep(i,1,k)if(s[i]=='?')S|=(1<<(k-i));
			write(dfs1(0,S,1));
		}
	}
}

标签:cnt,le,int,复杂度,id,step,2018,JOI,Final
From: https://www.cnblogs.com/dcytrl/p/18633661

相关文章

  • 请解释下join和split两个方法有什么作用?
    在前端开发中,join和split是两个常用的字符串处理方法。它们分别用于将数组元素连接成一个字符串和将一个字符串拆分为数组。1.join方法join方法是数组(Array)对象的一个方法,用于将数组中的所有元素连接成一个字符串。你可以指定一个分隔符(可选),用于在元素之间添加。如果不指......
  • “物品复活”软件开发(Final) 总结文章
    在开发物品复活系统过程中,我深刻体会到软件工程中的一些关键概念和技术方法的应用。以下将从多个维度,结合软件工程的理论,回顾开发过程中的经验与收获。需求分析与功能设计在开发开始时,需求分析是整个软件工程过程中至关重要的一步。在这一步,我明确了系统的主要目标,即为用户提供......
  • CS61B srping 2018 lab03 https://sp18.datastructur.es/
    UnitTestingwithJUnit,Debugging准备装好CS61B插件(emmmmm,不装也没事)把lab2的IntList.java复制到lab3/IntList文件夹.看看关于测试的课程视频介绍啊?JUnit是java测试框架,现在要用JUnit进行单元测试,单元Unit就是把程序分成小块的单元,一个单元的功能尽量少,单独测试,......
  • Atcoder_cf17_final_j Tree MST
    这是我的第一道黑题!言归正传,题意是,给定一棵\(n\)个节点的树,现有有一张完全图,两点\(x\),\(y\)之间的边长为\(w_x+w_y+dis_{x,y}\),其中\(dis_{x,y}\)表示\(x\)和\(y\)在树上的距离,求完全图的最小生成树。常规的求最小生成树的算法有\(kruskal\)、\(prim\)。但是这里这......
  • ZJOI2016 旅行者 题解
    ZJOI2016旅行者题解题目大意:给定一个\(n\timesm\)的网格图,相邻的四连通的点之间有给定边权的双向边,有\(Q\)个离线询问,问两个点之间的最短路。\(n\timesm\le2\times10^4,Q\le10^5\)。发现了吗?和上次省选组的三角剖分那道题很像,这种平面图上的最短路很有可能是分治......
  • P8329 [ZJOI2022] 树
    设\(f(S)\)表示钦定第一颗树叶子集合为\(S\)的方案数,则有\(f(S)=\prod\limits_{i=2}^{n}(i-1-\sum\limits_{j=1}^{i-1}[j\inS])\)。同理,设\(g(T)\)表示钦定第二颗树中叶子集合为\(T\)的方案数。枚举第一颗树的叶子集合恰好为\(S\),第二颗树的叶子集合恰好为\(......
  • Solution - Luogu P11394 [JOI Open 2019] ウイルス実験
    首先可以根据字符串\(D\),\(\mathcal{O}(2^c|D|)\)(\(c\)为方向数\(4\))求出上下左右分别是否被感染时对应的最长连续段长度,用于后面的check。考虑到答案要求的最小值,于是可以考虑思考什么样的点不会作为最后的最小值的起始点。考虑到如果最先感染了点\(u\),且最终感染了点\(v......
  • 原核生物表达异源蛋白--最佳分泌信号肽筛选策略--思路来自2018年的文献
    枯草芽孢杆菌分泌生产异源蛋白的最佳信号肽的系统筛选J.Agric.FoodChem.2018,66,13141−13151原始文献链接:http://pubs.acs.org/action/showCitFormats?doi=10.1021/acs.jafc.8b04183实验方法:构建信号肽库:以α-淀粉酶AmyS作为报告蛋白,构建了一个包含173个Sec型信......
  • SYSCPC Final 2024 参赛总结
    SYSCPCFinal2024参赛总结赛前前一天下午回家过冬至,出去外面吃粤菜,在一家环境很俗的小店,但是人奇多,应该是老字号了,但烧鹅挺赞的。冬至并没有吃汤圆。早上六点起来,从家里到纪中,然后七点钟坐小巴到中大,大概在八点多到达。到场地,是分很多个机房比赛,发现送了保温杯,其实还送了衣......
  • forkjoin
    ForkJoin框架是Java并发包(java.util.concurrent)的一部分,主要用于并行计算,特别适合处理可以递归划分成许多子任务的问题,例如大数据处理、并行排序等。该框架的核心思想是将一个大任务拆分成多个小任务(Fork),然后将这些小任务的结果汇总起来(Join),从而达到并行处理的效果。publiccl......