zoukankan      html  css  js  c++  java
  • MAX(数论)

    Description

    小C有n个区间,其中第i个区间为[li,ri],小C想从每个区间中各选出一个整数,使得所有选出的数and起来得到的结果最大,请你求出这个值。

    Input Format

    第一行一个正整数n,表示区间个数。接下来n行,每行两个非负整数li,ri。

    (n leq 10^5, li leq ri leq 10^{18})

    Output Format

    输出一个整数,表示答案。

    Solution

    跟二进制有关,那么一般都要转化成二进制下操作,

    我们发现,最后的答案其实是可以看成(2^{k_1}+2^{k_2}+...2^{k_n}),

    那么其实就是选出来的数列化成二进制后第(k_1,k_2...k_n)位都为1,

    (k_i)越大就越优,那么就有了思路,按二进制为从高到低验证,

    如果第(i) 位符合条件,那么(Ans+=2^i) ,答案就算出来了,

    当符合条件的时候,需要特殊处理否则会影响到后面的判断,

    只要把所有区间都往左移动(2^i)即可,即减去(2^i),

    Code

    #include <cstdio>
    #include <algorithm>
    #define LL long long
    #define N 100010
    using namespace std;
    
    int n;
    LL Ans, l[N], r[N];
    
    inline LL read() {
    	LL x = 0, r = 1; char ch = getchar();
    	while (ch < '0' || ch > '9') {if (ch == '-')r = -1; ch = getchar();}
    	while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    	return x * r;
    }
    
    int main() {
    	scanf("%d", &n);
    	for (int i = 1; i <= n; ++i)
    		l[i] = read(), r[i] = read();
    	for (int k = 62; k >= 0; k--) {
    		LL pk = 1ll * 1 << k;
    		bool flag = 1;
    		for (int i = 1; i <= n; ++i)
    			if (r[i] < pk) flag = 0;
    		if (flag) Ans += pk;
    		for (int i = 1; i <= n; ++i) {
    			if (flag || l[i] >= pk) l[i] -= pk, r[i] -= pk;
    		}
    	}
    	printf("%lld
    ", Ans);
    	return 0;
    }
    
  • 相关阅读:
    为什么说http协议是无状态协议
    LR中获取当前系统时间的方法
    在Ubuntu Server下配置LAMP环境
    服务器性能监控
    性能测试:过程和重要指标
    LR中线程和进程的区别
    怎样获取Windows平台下SQL server性能计数器值
    用Excel创建SQL server性能报告
    Windows下部署Appium教程(Android App自动化测试框架搭建)
    性能测试指标
  • 原文地址:https://www.cnblogs.com/void-f/p/7747351.html
Copyright © 2011-2022 走看看