zoukankan      html  css  js  c++  java
  • CF1041F Ray in the tube

    挂上Chester大神的解题报告  

    有一个思维跳跃的地方,就是不应该枚举所有的$B$点,而是应该在选定一个$A$点之后枚举距离计算。

    然后我们发现枚举距离是$2^k$的长度就可以了,证明如下:

    假如距离$d = 2^k$,那么对于每一个$A$点如果能被经过$a_p$的点弹到,需要满足$a_iequiv a_p (Mod  2d)$,而对所有的$B$点,如果能被经过$a_p$的点弹到,需要满足$b_i + d equiv a_p (Mod 2d)$。

    那么对于一些其他的距离,我们的$d  = 2^k$的距离一定可以计算到$td$所包含的点,所以这样子就足够了。

    那么这样我们就可以枚举$d$然后去检验了,因为$d$的个数是$log(1e9)$个,然后用一个$map$记录一下同余的个数有几个更新答案即可。

    时间复杂度$O(nlognlog1e9)$。

    Code:

    #include <cstdio>
    #include <cstring>
    #include <map>
    using namespace std;
    
    const int N = 1e5 + 5;
    const int MaxN = (int)1e9;
    
    int n, m, ans = 2, a[N], b[N];
    map <int, int> cnt;
    
    inline void read(int &X) {
        X = 0; char ch = 0; int op = 1;
        for(; ch > '9' || ch < '0'; ch = getchar())
            if(ch == '-') op = -1;
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            X = (X << 3) + (X << 1) + ch - 48;
        X *= op;
    }
    
    inline void chkMax(int &x, int y) {
        if(y > x) x = y;
    }
    
    int main() {
        int y;
        read(n), read(y);
        for(int i = 1; i <= n; i++) read(a[i]);
        read(m), read(y);
        for(int i = 1; i <= m; i++) read(b[i]);
        
        for(int d = 1; d < MaxN; d <<= 1) {
            int P = d << 1;
            cnt.clear();
            for(int i = 1; i <= n; i++) cnt[a[i] & (P - 1)]++;
            for(int i = 1; i <= m; i++) cnt[(b[i] + d) & (P - 1)]++;
            
            for(map <int, int> :: iterator it = cnt.begin(); it != cnt.end(); ++it)
                chkMax(ans, it -> second);
        }
        
        printf("%d
    ", ans);
        return 0;
    }
    View Code
  • 相关阅读:
    45 岁,还写代码吗?
    给你 8 个接私活的网站
    一文回顾 Java 入门知识(下)
    5 种前途迷茫的编程语言
    JVM 内存的结构模型、堆与堆栈原理、对象在内存中的结构
    mysql 索引是否能提高UPDATE,DELETE,INSERT 处理速度
    【诈尸】【游戏】多人联机游戏推荐
    250.统计同值子树
    366. 寻找二叉树的叶子节点
    156.上下翻转二叉树
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9673505.html
Copyright © 2011-2022 走看看