• BZOJ 2728: [HNOI2012]与非


    2728: [HNOI2012]与非

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 786  Solved: 371
    [Submit][Status][Discuss]

    Description

    Input

    输入文件第一行是用空格隔开的四个正整数N,K,L和R,接下来的一行是N个非负整数A1,A2……AN,其含义如上所述。 100%的数据满足K≤60且N≤1000,0<=Ai<=2^k-1,0<=L<=R<=10^18

    Output

    仅包含一个整数,表示[L,R]内可以被计算出的数的个数

    Sample Input

    3 3 1 4
    3 4 5

    Sample Output

    4

    HINT

    样例1中,(3 NAND 4) NADN (3 NAND 5) = 1,5 NAND 5 = 2,3和4直接可得。

    Source

    day1

    分析:

    如果把与非操作换成异或操作应该就是裸的线性基的题目,现在问题就转化为了求与非操作下的线性基...

    我们考虑通过与非操作可以得到所有的位运算:

    $~A=A nand A$

    $A and B=~(A nand B)$

    $A orB=~((~A) and (~B))$

    $A xor B=(A or B) and (A nand B)$...

    然后我们发现所有的位运算,对于某些位置,如果这些位置在每个数字中都相同,那么最后的结果这些位置也是相同的...

    而因为我们可以得到所有的位运算所以这些位置最后都可以为$1$,所以我们找出所有相同的位置作为线性基,一组相同的位置是线性基中的一个数...计算出线性基之后随便算一算就好了...

    具体找法就是我们选取当前枚举的位置,如果一个数字当前位置为$0$那么把它取反,然后把操作之后的所有数字$and$起来,这样相同的位置一定是$1$...

    代码:

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    //by NeighThorn
    #define int long long
    using namespace std;
    
    const int maxn=1000+5;
    
    int n,k,l,r,cnt,a[maxn],b[maxn],f[maxn];
    
    inline int calc(int x){
    	if(x==-1)
    		return -1;
    	int now=0,ans=0;
    	for(int i=1;i<=cnt;i++)
    		if((now|b[i])<=x)
    			now|=b[i],ans|=(1LL<<cnt-i);
    	return ans;
    }
    
    inline void xor_gauss(void){
    	int lala=(1LL<<k)-1,now;
    	for(int i=k-1;i>=0;i--)
    		if(!f[i]){
    			now=lala;
    			for(int j=1;j<=n;j++){
    				if((a[j]>>i)&1)
    					now&=a[j];
    				else
    					now&=~a[j]&lala;
    			}
    			b[++cnt]=now;
    			for(int j=0;j<=i;j++)
    				if((now>>j)&1)
    					f[j]=1;
    		}
    }
    
    signed main(void){
    	scanf("%lld%lld%lld%lld",&n,&k,&l,&r);
    	for(int i=1;i<=n;i++)
    		scanf("%lld",&a[i]);
    	xor_gauss();
    	printf("%lld
    ",calc(r)-calc(l-1));
    	return 0;
    }
    

      


    By NeighThorn

  • 相关阅读:
    libxml2 解析文档的例子
    FreeRTOS之任务优先级的分配
    idea中快速重写父类方法
    组件里面调用组建的方法
    sproot 注解学习记录 (含给实现类起名字的方法)
    直播技术没有那么神秘,你也可以DIY
    Java服务端API接口统一加密和解密
    把对象交给spring管理的3种方法及经典应用
    Dart空安全的底层原理与适配
    Dart 中 final和const 区别
  • 原文地址:https://www.cnblogs.com/neighthorn/p/6433312.html
Copyright © 2020-2023  润新知