正题

题目链接:https://uoj.ac/problem/750


题目大意

给出nnn个数字和一个ppp,保证2n>p2^n> p2n>p。现在要求一个序列www满足wi∈[−1,1]w_i\in[-1,1]wi​∈[−1,1],使得∑i=1nwiai≡0(modp)\sum_{i=1}^nw_ia_i\equiv 0\pmod p∑i=1n​wi​ai​≡0(modp)

1≤p<2n,1≤n≤40,0≤ai<p1\leq p<2^n,1\leq n\leq 40,0\leq a_i<p1≤p<2n,1≤n≤40,0≤ai​<p


解题思路

我们考虑从数字集合SSS中找两个数字和相同的集合T1,T2T_1,T_2T1​,T2​,那么T1−T1∩T2T_1-T_1\cap T_2T1​−T1​∩T2​和T2−T1∩T2T_2-T_1\cap T_2T2​−T1​∩T2​的和也相等,此时我们一边选111一边选−1-1−1即可,如果有一边是空的也行,这样另一边直接合法。

然后在SSS中选出集合的方案有2n2^{n}2n种,然后因为[0,p)[0,p)[0,p)有不超过这么多个数,所以肯定有重复的一个位置,所以肯定有解。

然后考虑怎么求这个解,看到这个范围我们考虑一下折半,我们搜出左右两边数字和的集合Sl,SrS_l,S_rSl​,Sr​。

如果左边或者右边有重复的就直接结束先,这样我们就能保证左右没有重复了,此时我们需要找到a,b∈Sl,c,d∈Sra,b\in S_l,c,d\in S_ra,b∈Sl​,c,d∈Sr​,使得a+c=b+da+c=b+da+c=b+d,因为两个集合的都很大,这个看起来很不可做。

但是我们知道一定有解,这个条件肯定是有用的,我们考虑二分一下这个和。每次分割成左右两个区间[l,mid],[mid+1,r][l,mid],[mid+1,r][l,mid],[mid+1,r],我们求出有多少对x∈Sl,y∈Srx\in S_l,y\in S_rx∈Sl​,y∈Sr​满足x+y∈[l,mid]x+y\in[l,mid]x+y∈[l,mid],如果超过mid−l+1mid-l+1mid−l+1那么答案肯定在左区间,否则在右区间。

时间复杂度:O(2n2n)O(2^{\frac{n}{2}}n)O(22n​n)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define ll long long
using namespace std;
const ll N=45,M=1<<20;
ll n,p,L1,L2,a[N];
map<ll,ll> mp;pair<ll,ll> f[M],g[M];
bool check(ll l,ll r){int L=0,R=0;ll ans=0;for(int i=L1-1;i>=0;i--){while(R<L2&&f[i].first+g[R].first<=r)R++;while(L<L2&&f[i].first+g[L].first<l)L++;ans+=R-L;}L=0;R=0;for(int i=L1-1;i>=0;i--){while(R<L2&&f[i].first+g[R].first-p<=r)R++;while(L<L2&&f[i].first+g[L].first-p<l)L++;ans+=R-L;}return ans>(r-l+1);
}
void solve(ll ansL,ll ansR){ll k=ansL&ansR;ansL-=k;ansR-=k;for(int i=0;i<n;i++){if((ansL>>i)&1)printf("1 ");else if((ansR>>i)&1)printf("-1 ");else printf("0 ");}return;
}
signed main()
{scanf("%lld%lld",&n,&p);for(ll i=0;i<n;i++)scanf("%lld",&a[i]);L1=(1<<n/2);for(int s=1;s<L1;s++){for(int i=0;i<n/2;i++)if((s>>i)&1)(f[s].first+=a[i])%=p;f[s].second=s;}L2=(1<<n-n/2);for(int s=1;s<L2;s++){for(int i=0;i<(n-n/2);i++)if((s>>i)&1)(g[s].first+=a[i+n/2])%=p;g[s].second=s;}sort(f+1,f+L1);sort(g+1,g+L2);for(int i=1;i<L1-1;i++)if(f[i].first==f[i+1].first){solve(f[i].second,f[i+1].second);return 0;}for(int i=1;i<L2-1;i++)if(g[i].first==g[i+1].first){solve(g[i].second<<(n/2),g[i+1].second<<(n/2));return 0;}ll l=0,r=p-1;while(l<r){ll mid=(l+r)>>1;if(check(l,mid))r=mid;else l=mid+1;}ll z=0,ansL=0,flag=0;for(int i=L1-1;i>=0;i--){while(z<L2&&f[i].first+g[z].first<r)z++;if(f[i].first+g[z].first==r){if(!flag)ansL=f[i].second+(g[z].second<<n/2),flag=1;else{solve(ansL,f[i].second+(g[z].second<<n/2));return 0;}}}z=0;for(int i=L1-1;i>=0;i--){while(z<L2&&f[i].first+g[z].first-p<r)z++;if(f[i].first+g[z].first-p==r){if(!flag)ansL=f[i].second+(g[z].second<<n/2),flag=1;else{solve(ansL,f[i].second+(g[z].second<<n/2));return 0;}}}//    for(ll i=0;i<L2;i++)mp[g[i]]=i+1;
//  for(ll i=0;i<L1;i++){//      ll x=(l+p-f[i])%p;
//      if(mp[x]){//          mp[x]--;
//          if(!mp[x]&&!i)continue;
//      }
//  }return 0;
}

uoj#750-[UNR #6]小火车【二分,折半,鸽笼原理】相关推荐

  1. Python011: Python大作业之移动的小火车动画(四)代码实现

    书接上文:Python010: Python大作业之移动的小火车动画(三)结果显示 0.注意: ​ 该项目使用的库和资源说明如下: pygame 2.0.1 (SDL 2.0.14, Python 3 ...

  2. Python008: Python大作业之移动的小火车动画(一)

    Python大作业 1. 要求 使用Python语言,使用的库不限 如下图1的火车轨道 如下图2的火车(2节车厢) 小火车可以在轨道上动态的运行 小火车的大小可调.轨道的大小可调 2. 用到的第三方库 ...

  3. 挖洞经验 | 看我如何发现“小火车托马斯”智能玩具APP聊天应用漏洞

    最近,我向智能玩具厂商ToyTalk提交了两个APP相关的漏洞并获得了$1750美金奖励,目前,漏洞已被成功修复,在此我打算公开详细的漏洞发现过程,以便其他APP开发人员将这种脆弱性威胁纳入开发过程的 ...

  4. 传说中的“铁索连环”?苹果要把无人车串成小火车

    晓查 发自 凹非寺 量子位 报道 | 公众号 QbitAI 苹果最近提交了一项辣眼睛的专利:把无人驾驶汽车串起来,是真的串起来,而且是有线的! 苹果把这项专利叫做Peloton,来源于法语,是指自行车 ...

  5. Linux趣味小游戏,嘟嘟嘟,小火车来了

    让我们来学习一下,用Linux制作小火车的运动,嘟嘟嘟... 1.上网,打开网络. 2.epel源:配置第三方epel源更新地址 curl -s -o /etc/yum.repos.d/epel.re ...

  6. arduino小火车交通灯

    今天做了一个arduino小火车信号灯的程序, 5.6.7分别接了一个红绿蓝三盏灯,A0接了个光敏电阻一端测光敏电阻模拟量. 没有小火车经过时,绿灯亮.当小火车来的时候会遮挡光线,因此A0口检测到光敏 ...

  7. 金山小火车【转自官网】(如果错误,请留言)

    金山卫和上海南站间的双向小火车具体时刻表,分日常和节假日,直达和站站停! 金山卫->上海南站(双休日) 车次 类型 出发站 到达站 C3652 站站停 金山卫06:00开 (1) 07:00到南 ...

  8. Linux系统小惊喜:开往2022虎年的小火车

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.安装sl工具包 二.执行sl命令小火车开起来 三. 连续开车 前言 ` 神牛辞旧岁,金虎迎新春. 马上就到2022 ...

  9. acm 2119 小火车嘟嘟

    [提交][状态][讨论版][命题人:171530145] 题目描述 有一列小火车,每天在固定的时间鸣笛,日复一日,年复一年.终于,小火车鸣笛鸣累了.它想找人来接盘. 虽然一天有24小时,小火车却是只在 ...

最新文章

  1. java 调用webservice的各种方法总结
  2. RocketMQ:Producer启动流程与消息发送源码分析
  3. java jdk安装失败 mac_Mac javaJDK安装遇到的坑和环境变量配置2019-07-09.
  4. 【算法入门漫画】:什么是字符串匹配算法?
  5. SQL Server 性能调优(方法论)
  6. 前端:几个操作URL的实用函数
  7. 【Redis】redis数据类型及应用场景
  8. pytorch调用不了多个gpu_pytorch利用多个GPU并行计算
  9. 相机裁剪旋转_感受大画幅相机随心所欲的景深控制
  10. window对象与document对象的区别
  11. js 设置焦点 判断控件是否获得焦点 判断哪个控件获得焦点
  12. error: Zip file too big (greater than 4294959102 bytes)
  13. Matlab图像、矩阵旋转、翻转函数 rot90、flipud、fliplr、imrotate、flipdim、flip详解
  14. unity学习之NGUI做NPC对话
  15. python 应用程序无法正常启动 000007b_“应用程序无法正常启动(oxc000007b)”解决方案...
  16. SDY2205使用说明书
  17. 用ffmpeg进行音频格式转换、剪切、合并、音量调整等
  18. java -英语单词接龙
  19. python 3d绘图旋转_Python和Matplotlib:在Jupyter Noteb中使3D绘图具有交互性
  20. SHA256 Hashes

热门文章

  1. 清默网络多区域 OSPF
  2. 获取光标位置及动态设置光标到指定位置
  3. UWB室内定位系统的优势与好处
  4. Server-Sent Events 一种轻量级的Push方式
  5. 我支持刘翔,理由有三
  6. 中心极限定理与大数定理理解
  7. HTML学生个人网站作业设计:动漫网站设计——斗破苍穹动漫(6页) HTML+CSS+JavaScript 简单DIV布局个人介绍网页模板代码 DW学生个人网站制作成品下载
  8. HtmlUnit学习总结
  9. placement new的用法
  10. (python代码+讲解)重叠社区发现EAGLE层次算法的实现