bzoj:4762: 最小集合

原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4762

mark一下,有空要好好弄懂

#include<cstdio>
#include<algorithm>
using namespace std;
int read_p,read_ca;
inline int read(){
    read_p=0;read_ca=getchar();
    while(read_ca<‘0‘||read_ca>‘9‘) read_ca=getchar();
    while(read_ca>=‘0‘&&read_ca<=‘9‘) read_p=read_p*10+read_ca-48,read_ca=getchar();
    return read_p;
}
const int MOD=1e9+7;
int n,a,mmh[2][1024][1024];
inline void M(int &x){while(x>=MOD)x-=MOD;while(x<0)x+=MOD;}
int main(){
    register int i,j,k;
    n=read();mmh[0][0][0]=1;
    for (i=1;i<=n;i++){
        a=1023-read();
        for (j=0;j<1024;j++)
        for (k=j;;k=(k-1)&j){
            mmh[i&1][j][k]=mmh[i&1^1][j][k];
            if (!k) break;
        }

        for (j=0;j<1024;j++)
        for (k=j;;k=(k-1)&j){
            M(mmh[i&1][j|a][k^(k&a)]+=mmh[i&1^1][j][k]);
            M(mmh[i&1][j|a][(k^(k&a))|(a^(j&a))]-=mmh[i&1^1][j][k]);
            if (!k) break;
        }
    }
    printf("%d\n",mmh[n&1][1023][0]);
}

时间: 2024-10-14 01:39:31

bzoj:4762: 最小集合的相关文章

BZOJ 1797 最小割

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1797 题意:给出一个有向图,每条边有流量,给出源点汇点s.t.对于每条边,询问:(1)是否存在一个最小割包含该边?(2)是否所有的最小割都包含该边? 思路:首先求最大流,在残余网络中求强连通 分量.对于每条原图中的边(最大流中添加的反向边不算)<u,v>,该边的残余流量为0且u和v在两个不同的强连通分量中,则存在一个最小割 包含该边:在上述满足且u与s在一个连通分量.v与t在一个连通

BZOJ 1486 最小圈(二分+判负环)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1486 题意:给出一个有向图,边有权值.找到一个环,使得环上边的权值之和除以环上边的个数最小. 思路:二分答案x,每条边权值减去x,之后 找负环.从每个顶点开始DFS,记录到达某个顶点的距离,设当前DFS的顶点为u,距离dis[u].下一个顶点v, 权值w,则dis[u]+w<=0时才DFS(v).另外,若v是已经遍历过的,且dis[u]+w-dis[v](这个dis[v]是之前遍历时

1616 最小集合 51NOD(辗转相处求最大公约数+STL)

1616 最小集合 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题  收藏  关注 A君有一个集合. 这个集合有个神奇的性质. 若X,Y属于该集合,那么X与Y的最大公因数也属于该集合. 但是他忘了这个集合中原先有哪些数字. 不过幸运的是,他记起了其中n个数字. 当然,或许会因为过度紧张,他记起来的数字可能会重复. 他想还原原先的集合. 他知道这是不可能的-- 现在他想知道的是,原先这个集合中至少存在多少数. 样例解释: 该集合中一定存在的是{1,2,3,4,6

BZOJ 2458 最小三角形 | 平面分治

BZOJ 2458 最小三角形 题面 一个平面上有很多点,求他们中的点组成的周长最小的三角形的周长. 题解 跟平面最近点对差不多,也是先把区间内的点按x坐标从中间分开,递归处理,然后再处理横跨中线的三角形. 如何缩小范围?设左右两个子区间发现的最小周长是d,则与中线距离超过d / 2都没有用了,对于一个点,所有与它距离超过d / 2的点也都没有用. #include <cstdio> #include <cstring> #include <cmath> #includ

BZOJ 2568 比特集合

题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2568 题意:维护一个集合S,支持以下操作: (1)INS M : 将元素 M 插入到集合S中:(2)DEL M : 将集合S中所有等于 M 的元素删除:(3)ADD M : 将集合S中的所有元素都增加数值M :(4)QBIT k : 查询集合中有多少个元素满足其二进制的第 k位为 1 . 思路:我看的这个 https://github.com/strongoier/OJ/tree

bzoj 2150 最小路径覆盖

最小路径覆盖问题是:给定一个DAG,该DAG的一个路径覆盖是一个路径的集合,使得每个点属于且仅属于其中一条路径,问题就是求一个大小最小的路径集合. 做法是将每个点A拆成两个点A1,A2,如果A->B,那么连A1->B2求一个最大匹配. 一个结论是:最小路径数 = 点数 - 最大匹配 证明的大概思路是: 一个路径覆盖与一个边独立集(即一个匹配)一一对应. 一个路径覆盖的路径数 = 点数 - 匹配数 ( 因为 路径数+每条路径的边数和-1 = n个点的无向联通无环图的边数 , 匹配数等于每条路径的

51nod 1616 最小集合(枚举倍数)

分析:也就是取任意多个数,它们的最大公约数都在这个集合里.考虑到ai比较小,可以枚举小于a中最大值的所有数,判断是否为其中若干个数的gcd.记c[k]为a中k的倍数的个数,然后枚举k的倍数i*k,c[i]<2直接跳过,如果c[i*k]==c[k],说明k的那些倍数也同时是i*k的倍数,k就可以不在集合中,反之,如果任意i,c[i*k]<c[k],说明存在一个倍数和其它k的倍数的gcd是k,所以k一定在集合中.两次枚举倍数,复杂度为O(nlogn). 1 #include<iostream

bzoj 2734: [HNOI2012]集合选数

Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 779  Solved: 456[Submit][Status][Discuss] Description <集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x 不能在该子集中.同学们不喜欢这种具有枚举性 质的题目,于是把它变成了以下问题:对于任意一个正整数 n≤100000,如何求出{1, 2,...,

BZOJ 4349: 最小树形图

Description \(n\)个节点,每个节点有一个攻击代价和需要攻击的次数. 有\(k\)个关系,攻击\(x\)后,\(y\)的攻击代价变成\(z\). Solution 朱刘算法. 这个好像就是求什么最小树形图的东东... 最小树形图跟最小生成树差不多,不过最小生成树是无向图,最小树形图是有向图,让一个节点和其他节点联通的最小代价. 这个建模也非常容易,只需要确定第一次的攻击即可,之后的一定都以最小代价攻击. 朱刘算法也很简单,步骤就是 找到每个节点的最小入边. 统计答案. 找环,缩环,