[BZOJ5285][HNOI2018]寻宝游戏
先贴一段出题人的话:
当时出题的时候很紧张,是真的紧张,因为觉得实在是太水了。
...
我当时很怕结果出来十几个AC,全场70。然后就再也没人找我出题了。
当时就不停的想HNOI有什么水题,是不是比我这个更水来安慰自己。
首先考虑DP,发现如果按照每位依次DP的话不满足无后效性,所以我们从后往前做。
相当于BFS,列出一个真值表,把8种情况都考虑进去即可。
这样我们就可以得到。。10分了。
https://www.cnblogs.com/lzdhydzzh/p/8850109.html
发现如果全都不强制或者有一位存在不合法情况,都可以直接判掉并剪枝,这样每层最多状态数最多为2。
手写bitset压64位跑一下可以过。$O(\frac{nmq}{64})$
有点麻烦,看注释吧。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #define rep(i,l,r) for (int i=l; i<=r; i++) 6 using namespace std; 7 8 typedef unsigned long long ull; 9 const int N=1010,mod=1e9+7; 10 int bl,n,m,Q,res,dt,cur,tot; 11 ull ans,mi[N]; 12 13 struct bitset{ 14 ull p[80]; 15 void clear(){ rep(i,0,bl) p[i]=0; } 16 void read(){ 17 memset(p,0,sizeof(p)); char ch=getchar(); 18 while (!isdigit(ch)) ch=getchar(); 19 for (int i=0; i<m; i++,ch=getchar()) p[i>>6]|=(((ull)(ch-'0'))<<(i&63));//压64位 20 } 21 }s[N],f[N],nt,t1,t2,v1,v2,g,c1,c2,que[2][4]; 22 23 void init(){ 24 bl=(m-1)>>6; mi[0]=1; 25 rep(i,1,n) mi[i]=(mi[i-1]<<1)%mod; 26 memset(nt.p,0,sizeof(nt.p)); 27 for (int i=0; i<m; i++) nt.p[i>>6]|=(1llu<<(i&63)); 28 rep(i,1,n){ 29 s[i].read(); 30 rep(j,0,bl) f[i].p[j]=s[i].p[j]^nt.p[j]; 31 } 32 } 33 34 int main(){ 35 freopen("bzoj5285.in","r",stdin); 36 freopen("bzoj5285.out","w",stdout); 37 scanf("%d%d%d",&n,&m,&Q); init(); 38 while (Q--){ 39 g.read(); dt=ans=cur=0; que[cur][++dt].clear();//0表示必须和询问串一样,1表示不强制 40 for (int i=n; i; i--){ 41 tot=dt; cur^=1; dt=0; 42 rep(j,1,tot){ 43 bool f1=1,f2=1,l1=1,l2=1; 44 rep(k,0,bl){ 45 if (!f1 && !f2) break; 46 if (que[cur^1][j].p[k]==nt.p[k]){//如果都不强制的话就不需要具体考虑了 47 if (f1) t1.p[k]=nt.p[k]; 48 if (f2) t2.p[k]=nt.p[k]; 49 continue; 50 } 51 //v1为或,v2为且 52 if (f1) v1.p[k]=s[i].p[k]&(s[i].p[k]^g.p[k]);//询问串这一位为0,当前串这一位为1 53 if (f2) v2.p[k]=g.p[k]&(s[i].p[k]^g.p[k]);//询问串这一位为1,当前串这一位为0 54 if (f1 && (v1.p[k]&que[cur^1][j].p[k])!=v1.p[k]) f1=0;//判掉-1 55 if (f2 && (v2.p[k]&que[cur^1][j].p[k])!=v2.p[k]) f2=0;//判掉-1 56 if (f1) t1.p[k]=que[cur^1][j].p[k]|(s[i].p[k]^v1.p[k]);//生成新的要求,如果本来就不强制则必定不强制,具体根据真值表 57 if (f2) t2.p[k]=que[cur^1][j].p[k]|(f[i].p[k]^v2.p[k]);//生成新的要求,如果本来就不强制则必定不强制,具体根据真值表 58 if (f1 && t1.p[k]!=nt.p[k]) l1=0;//判断是否全部不强制 59 if (f2 && t2.p[k]!=nt.p[k]) l2=0;//判断是否全部不强制 60 } 61 if (f1){ if (l1) ans=(ans+mi[i-1])%mod; else que[cur][++dt]=t1; } 62 if (f2){ if (l2) ans=(ans+mi[i-1])%mod; else que[cur][++dt]=t2; } 63 } 64 } 65 rep(j,1,dt){ 66 bool f1=1; 67 rep(k,0,bl) if ((que[cur][j].p[k]^nt.p[k])&g.p[k]){ f1=0; break; }//最后对 与 判断一遍是否合法 68 ans+=f1; 69 } 70 printf("%llu\n",ans); 71 } 72 return 0; 73 }
上面好像是出题人并不喜欢的暴力解法,很不优美,我们把它扔进垃圾桶。
正解是把或看成1,与看成0,通过总结规律发现题目可以变成比大小问题。
https://kelin.blog.luogu.org/solution-p4424
非常神的想法,代码也很简单,将操作数排序然后看哪个区间是合法的即可。
1 #include<cstdio> 2 #include<algorithm> 3 #define rg register int 4 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 5 using namespace std; 6 7 const int N=5010,mod=1000000007; 8 int n,m,q,c[2],a[N],b[N],s[N],t[N],mi[N]; 9 char p[N]; 10 11 int up(int x,int y){ x+=y; return (x>=mod)?x-mod:x; } 12 int dn(int x,int y){ x-=y; return (x<0)?x+mod:x; } 13 14 int main(){ 15 freopen("bzoj5285.in","r",stdin); 16 freopen("bzoj5285.out","w",stdout); 17 scanf("%d%d%d",&n,&m,&q); 18 mi[1]=1; rep(i,2,n+1) mi[i]=(mi[i-1]<<1)%mod; 19 rep(i,1,m) a[i]=i; 20 rep(i,1,n){ 21 scanf("%s",p+1); c[0]=0; c[1]=m; 22 rep(j,1,m) if (p[j]=='1') s[j]=up(s[j],mi[i]); else c[0]++; 23 for (int j=m; j; j--) b[c[p[a[j]]-48]--]=a[j]; 24 swap(a,b); 25 } 26 rep(i,1,m) t[i]=s[a[i]]; t[m+1]=mi[n+1]; 27 while (q--){ 28 scanf("%s",p+1); int x=m+1,y=0; 29 for (int i=m; i; i--) if (p[a[i]]=='0') { y=i; break; } 30 rep(i,1,m) if (p[a[i]]=='1') { x=i; break; } 31 printf("%d\n",(x<y)?0:dn(t[x],t[y])); 32 } 33 return 0; 34 }
转载于:https://www.cnblogs.com/HocRiser/p/8954335.html
[BZOJ5285][HNOI2018]寻宝游戏相关推荐
- [bzoj5285][Hnoi2018]寻宝游戏【复杂度分析】
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=5285 [题解] 考虑最后一个影响一个二进制位的数. 如果出现"&0 ...
- bzoj 5285: [Hnoi2018]寻宝游戏
Description Solution 把输入的 \(n\) 个二进制数看作一个大小为 \(n*m\) 的矩阵 把每一列压成一个二进制数,其中最高位是最下面的元素 然后就有了 \(m\) 个二进制数 ...
- HNOI2018寻宝游戏
https://www.luogu.org/problemnew/show/P4424 题解 我们首先按位考虑. 如果有一位最终的结果为1,那么我们可以把树的序列看成一个二进制数,先出现的在底位,后出 ...
- SDOI2015寻宝游戏 dfs序+set
SDOI2015寻宝游戏 好像是一道虚树入门题? 虚树???不会不会我弱死了.. Solution: 关键点间的最小路径,就是在保证尽量少走重复路的前提下走出来的一条经过所有关键点的路径. 基于这个思 ...
- 河北工业大学c语言寻宝游戏,计算机技术基础(c语言)课程设计寻宝游戏.doc
计算机技术基础(c语言)课程设计寻宝游戏 计算机技术基础(c语言)课程设计 寻宝游戏 #include #include #include #include #include #define ESC ...
- hdu 6289 寻宝游戏
寻宝游戏 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others) Total Sub ...
- 寻宝游戏 - 利用iBeacon特性设计的iOS线下寻宝游戏 - 物联网小游戏
寻宝游戏 - 利用iBeacon特性设计的iOS线下寻宝游戏 作者简介 科科香,程序员 方向:IoT,方案集成,喜好各种新鲜东东 转载请注明出处 iBeacon简介 iBeacon(下面简称Beaco ...
- minecraft_使用MCDungeon将地牢,废墟和寻宝游戏添加到您的Minecraft世界中
minecraft If you've grown tired of exploring the vanilla Minecraft world and the thrill of stumbling ...
- 许嵩续约太合音乐集团 携手开启《寻宝游戏》
7月24日,许嵩<寻宝游戏>发布会暨续约仪式在北京顺利召开.在推出新专辑<寻宝游戏>之际,也宣布续约太合音乐集团,启动未来"无限"可能. 许嵩畅谈新专< ...
- 【BZOJ 3991】 [SDOI2015]寻宝游戏
3991: [SDOI2015]寻宝游戏 Time Limit: 40 Sec Memory Limit: 128 MB Submit: 251 Solved: 137 [Submit][Status ...
最新文章
- 您会让自己的小孩将来从事软件研发吗?
- 张钹、朱松纯、黄铁军等同台激辩:人工智能的“能”与“不能”
- Vue单文件组件环境配置
- linux 启动2个tomcat,在LINUX中启动多个TOMCAT
- 你值得拥有:25个Linux性能监控工具
- php使用redis生成自增序列号码,Redis使用Eval多个键值自增的操作实例
- PHP实现redis限制单ip、单用户的访问次数功能
- 前端学习(3266):js中this的指向
- 面向对象之类的内建函数
- python中的def语句输出1000以内的回文_各种方法测试回文的性能[Python]
- 安卓(android)建立项目时失败,出现Android Manifest.xml file missing几种解决方法?(总结中)
- mysql innodb_double_write特性
- #{}不自动改参数类型_C++笔记——参数传递中的指针传递和引用传递
- 6-14漏洞利用-rpcbind漏洞利用
- win10 IDEA企业版下载及破解
- Java读取计算 PPT,Word,excel的页数
- centos 查看版本号方法
- mysql drop表明_MySQL DROP TABLE会完全删除表还是仅删除结构?
- Frameworks Detected: Web framework is detected
- 含义:Web1.0、Web2.0、Web3.0、Web4.0、Web5.0、Web6.0