【二进制优化】Codeforces - 1041 - F. Ray in the tube

题目链接<http://codeforces.com/contest/1041/problem/F>


题意:

在两个反射面上取一点发射一道激光,两个反射面上装了一些传感器,问最多有几个传感器能接收到激光。


题解:

首先,题目给出了反射面的纵坐标,这是没有用的,我们只需要考虑横坐标的距离即可。

然后总体思路是:

1)枚举步长。

2)处理出每个点在此步长下的状态,并用map记录每个状态的数量。

3)再枚举起点(起点只需枚举传感器的位置)计算每个起点下的答案。

后面两个复杂度是在1e5级别的,而第一个的复杂度能够达到1e9。

仔细推敲或者参考题解后就可以发现,步长只需枚举2^{l}的情况,这样复杂度可以降到30。

简单证明一下,如果步长不是2^{l},那么步长可以化为2^{l}*(2*x+1)的形式,很容易发现前者是包含后者的,如果在图上进行模拟的话会更清晰。


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+7;
int n,m,y,a[N],b[N];
map<int,int>aa,bb;
int main(){
    scanf("%d%d",&n,&y);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    scanf("%d%d",&m,&y);
    for(int i=1;i<=m;i++)
        scanf("%d",&b[i]);
    int ans=0;
    if(n) ans++;if(m) ans++;
    int mod=2;
    for(int k=2;k<=30;k++){
        aa.clear(),bb.clear();
        for(int i=1;i<=n;i++)
            aa[a[i]%mod]++;
        for(int i=1;i<=m;i++)
            bb[b[i]%mod]++;
        for(int i=1;i<=n;i++)
            ans=max(ans,aa[a[i]%mod]+bb[(a[i]%mod+mod/2)%mod]);
        for(int i=1;i<=m;i++)
            ans=max(ans,bb[b[i]%mod]+aa[(b[i]%mod+mod/2)%mod]);
        mod*=2;
    }
    printf("%d\n",ans);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值