----------------------------------------------------------------------------

一题题目:

一题题解:

  • 这个题目哪来入门再好不过了,支老板之前没有接触过这个东西,然后一点即通:就是把一个int(32位)拆成32个只放0或1的位置,然后这32个的单点操作或者32个一起操作的复杂度是O(1),所以长度位N的bitset的一次单点操作是O(1),整体操作是O(N/w),其中w=32。(long long 是64)。
  • 然后Bitset还有强大是&和|功能,以及count(1)等功能。
  • 但是Bitset最厉害的地方在于优化图论的dfs部分: 我们知道,dfs的时候对于当前点X,会继续访问和X有关联的所有点,continue忽略vis过的点。而有了bitset,我们可以直接得到有关联的,而且没有vis过的点,这样可以保证不去访问不必要的边,这在稠密图里改进极大。

 

-----------------------------------------------------------------------------

二题题目:

二题题解:

  • 跳过缩点建图。
  • 第一部分是求Bitset,得到每个点可以访问到的点。 
  • 第二部分求对应的权值和,巧妙的利用了分块来优化,复杂度/13。而且这个13的选择也是经过计算的,2^13<n,保证分块计算的复杂度影响小于前面的复杂度,新技能,学到了。

POJ3275:Ranking the Cows

题意:有N头奶牛,现在给出M对产奶量关系U>V,问至少还需要知道多少奶牛可以做到全部奶牛产奶关系。

思路:有向图,问至少再加多少边,使得任意两点S、T的可以到达(S到达T或者到达S)。闭包传递后不能到达的需要加边,ans++。

至于为什么ans++,可以参考,http://www.cnblogs.com/hua-dong/p/8538980.html

Floyd稍微优化:    注意边少,可以加一维限制,勉强通过。

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. using namespace std;
  7. const int maxn=;
  8. int mp[maxn][maxn];
  9. int main()
  10. {
  11. int N,M,ans,i,j,k;
  12. while(~scanf("%d%d",&N,&M)){
  13. ans=;
  14. memset(mp,,sizeof(mp));
  15. for(i=;i<=M;i++){
  16. scanf("%d%d",&j,&k);
  17. mp[j][k]=;
  18. }
  19. for(k=;k<=N;k++)
  20. for(i=;i<=N;i++)
  21. if(mp[i][k])
  22. for(j=;j<=N;j++)
  23. if(mp[k][j]) mp[i][j]=;
  24. for(i=;i<=N;i++)
  25. for(j=i+;j<=N;j++)
  26. if(!mp[i][j]&&!mp[j][i])
  27. ans++;
  28. printf("%d\n",ans);
  29. }
  30. return ;
  31. }

Bitset优化Floyd: 复杂度降为O(N^3/32)<3*10^7。

  1. #include<cstdio>
  2. #include<bitset>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<iostream>
  6. #include<algorithm>
  7. using namespace std;
  8. const int maxn=;
  9. bitset<maxn>mp[maxn];
  10. int main()
  11. {
  12. int N,M,ans,i,j,k;
  13. while(~scanf("%d%d",&N,&M)){
  14. ans=;memset(mp,,sizeof(mp));
  15. for(i=;i<=M;i++){
  16. scanf("%d%d",&j,&k);
  17. mp[j].set(k);
  18. }
  19.  
  20. for(k=;k<=N;k++)
  21. for(i=;i<=N;i++)
  22. if(mp[i][k])
  23. mp[i]|=mp[k];
  24. for(i=;i<=N;i++)
  25. for(j=i+;j<=N;j++)
  26. if(!mp[i][j]&&!mp[j][i])
  27. ans++;
  28. printf("%d\n",ans);
  29. }
  30. return ;
  31. }

POJ2443:Set Operation

题意:给定N个集合,Q次询问,对每次询问,求X,Y是否在同一集合出现过,注意X=Y时,X在一个集合里至少出现一次就满足了。

思路:用Bitset来表示每个元素在哪些集合出现过,如果X和Y出现的集合有交集,则满足。

  1. #include<cstdio>
  2. #include<bitset>
  3. #include<cstdlib>
  4. #include<iostream>
  5. #include<algorithm>
  6. using namespace std;
  7. const int maxn=;
  8. bitset<>s[maxn+];
  9. int read()
  10. {
  11. char c=getchar(); int res;
  12. while(c>''||c<'') c=getchar();
  13. for(res=;c>=''&&c<='';c=getchar()) res=(res<<)+(res<<)+c-'';
  14. return res;
  15. }
  16. int main()
  17. {
  18. int N,Q,i,num,x,y;
  19. while(~scanf("%d",&N)){
  20. for(i=;i<=maxn;i++) s[i].reset();
  21. for(i=;i<=N;i++){
  22. num=read();
  23. while(num--){
  24. x=read();
  25. s[x][i]=; //s[x].set(i);
  26. }
  27. }
  28. Q=read();
  29. while(Q--){
  30. x=read(); y=read();
  31. if((s[x]&s[y]).count()) puts("Yes"); //.any()
  32. else puts("No");
  33. }
  34. }
  35. return ;
  36. }

AtCoder - 3857:Median Sum

题意:给定N个数,有2^N-1种非空组合,求这些组合的和排序后的中位数。

思路:由对称性,知道中位数略大于Sum/2,所以我们从(Sum+1)/2后面所有的可能中,选择最近的一个。(证明见下面。)

具体实现:需要得到背包结果有哪些可能性,这个只需要Bitset加速一下即可得到。

证明:见前辈写的,很清晰,只要利用对称性即可。http://blog.csdn.net/zzzzone/article/details/79115522

  1. #include<bitset>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<iostream>
  5. #include<algorithm>
  6. using namespace std;
  7. const int maxn=;
  8. bitset<maxn*maxn+>s;
  9. int main()
  10. {
  11. int N,x,ans;
  12. while(~scanf("%d",&N)){
  13. s.reset(); ans=;
  14. s[]=;
  15. for(int i=;i<=N;i++){
  16. scanf("%d",&x);
  17. s|=(s<<x);
  18. ans+=x;
  19. }
  20. for(int i=(ans+)/;;i++){
  21. if(s[i]){
  22. printf("%d\n",i);
  23. break;
  24. }
  25. }
  26. }
  27. return ;
  28. }

CodeForce 914F:Substrings in a String

题意:

给定一个小写字符组成的字符串S;现在有Q种操作,对于每个操作Q,输入opt,如果opt==1,输入x,c,表示把S[x]改为c,(c是小写字母)。 如果opt==2,输入字符串T,输出S种有多少个字串==T(字串可以重叠),

思路:

          1,假设我们要统计S里有多少个T,先统计S里面字符==T[0]的是哪些,然后统计S中有T[0]的位置后面跟的字符==T[1]的有哪些,然后统计S中有T[0]的位置后面跟的字符==T[1]的而且后面跟的字符==T[2]的有哪些.....直到对比到S[len-1]。

2,最后利用位移可以得到某个区间的1的个数。

  1. #include<bitset>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cstdlib>
  5. #include<iostream>
  6. #include<algorithm>
  7. using namespace std;
  8. const int maxn=;
  9. bitset<maxn>s[],ans;
  10. char a[maxn],b[maxn],c[];
  11. void read(int &res)
  12. {
  13. char c=getchar();
  14. while(c>''||c<'') c=getchar();
  15. for(res=;c>=''&&c<='';c=getchar()) res=(res<<)+(res<<)+c-'';
  16. }
  17. int main()
  18. {
  19. scanf("%s",a+);
  20. int T=strlen(a+);
  21. int i,j,l,r,Q,opt;
  22. for(i=;i<=T;i++)
  23. s[a[i]-'a'].set(i);
  24. read(Q);
  25. while(Q--){
  26. read(opt);
  27. if(opt==){
  28. scanf("%d%s",&j,c);
  29. s[a[j]-'a'][j]=;
  30. s[(a[j]=c[])-'a'][j]=;
  31. }
  32. else {
  33. read(l); read(r);
  34. scanf("%s",b);
  35. int S=strlen(b);
  36. if(S>r-l+) {
  37. puts(""); continue;
  38. }
  39. ans.set();
  40. for(i=;i<S;i++){
  41. ans&=(s[b[i]-'a']>>i);
  42. }
  43. printf("%d\n",(ans>>l).count()-(ans>>(r-S+)).count());
  44. }
  45. }
  46. return ;
  47. }

CodeForces-707D:Persistent Bookcase

题意:现在有一个N*M的书架,有Q个操作,对于每个操作,输入opt:

如果opt==1,那么输入x,y,如果第x行第y列无书,则放一本书。

如果opt==2,那么输入x,y,如果第x行第y列有书,则取走那本书。

如果opt==3,那么输入x,将第x行有书的取走,无书的位置放一本。

如果opt==4,那么输入k,表示把书架的情况恢复为第k次操作后的样貌,k在当前操作之前。

思路:初看可能是可持久化数据结构,但是注意到整体操作顺序为有根树,可以DFS回溯,对于书架上的情况,可以直接积累或者Bitset假设。

  1. #include<bitset>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<iostream>
  5. #include<algorithm>
  6. using namespace std;
  7. const int maxn=;
  8. const int maxm=;
  9. bitset<maxn>s[maxn],P;
  10. int N,M,Q;
  11. int Laxt[maxm],Next[maxm],To[maxm],cnt;
  12. int opt[maxm],x[maxm],y[maxm],ans[maxm];
  13. void read(int &res)
  14. {
  15. char c=getchar(); res=;
  16. for(;c>''||c<'';c=getchar());
  17. for(;c<=''&&c>='';c=getchar()) res=(res<<)+(res<<)+c-'';
  18. }
  19. void add(int u,int v)
  20. {
  21. Next[++cnt]=Laxt[u];
  22. Laxt[u]=cnt;
  23. To[cnt]=v;
  24. }
  25. void dfs(int u,int Now)
  26. {
  27. for(int i=Laxt[u];i;i=Next[i]){
  28. int v=To[i];
  29. if(opt[v]==&&s[x[v]][y[v]]==) {
  30. s[x[v]][y[v]]=;
  31. ans[v]=Now+;
  32. dfs(v,ans[v]);
  33. s[x[v]][y[v]]=;
  34. }
  35. else if(opt[v]==&&s[x[v]][y[v]]==) {
  36. s[x[v]][y[v]]=;
  37. ans[v]=Now-;
  38. dfs(v,ans[v]);
  39. s[x[v]][y[v]]=;
  40. }
  41. else if(opt[v]==){
  42. ans[v]=Now-s[x[v]].count();
  43. s[x[v]]^=P;
  44. ans[v]+=s[x[v]].count();
  45. dfs(v,ans[v]);
  46. s[x[v]]^=P;
  47. }
  48. else {
  49. ans[v]=Now;
  50. dfs(v,ans[v]);
  51. }
  52. }
  53. }
  54. int main()
  55. {
  56. read(N); read(M); read(Q);
  57. for(int i=;i<=M;i++) P.set(i);
  58. for(int i=;i<=Q;i++){
  59. scanf("%d",&opt[i]);
  60. if(opt[i]==||opt[i]==) read(x[i]),read(y[i]);
  61. else read(x[i]);
  62. if(opt[i]==) add(x[i],i);
  63. else add(i-,i);
  64. }
  65. dfs(,);
  66. for(int i=;i<=Q;i++) printf("%d\n",ans[i]);
  67. return ;
  68. }

还有两个很重要的函数,去遍历哪些为1的地方,bitset._Find_first(),和bitset._Find_next(i)

【Bitset】重识的更多相关文章

  1. iOS开发——项目篇—高仿百思不得姐 05——发布界面、发表文字界面、重识 bounds、frame、scrollView

    加号界面(发布模块) 一.点击加号modal出发布模块,创建控件,布局控件1)使用xib加载view,如果在viewDidLoad创建控件并设置frame 那么self.view 的宽高 拿到的是xi ...

  2. 重识linux-SSH中的SFTP

    重识linux-SSH中的SFTP 1 SFTP也是使用SSH的通道(port 22) 2 SFTP是linux系统自带的功能 3 连接上主流的ftp软件都支持sftp协议 比如flashfxp,fi ...

  3. 重识linux-linux系统服务相关

    重识linux-linux系统服务相关 1 tcp wrappers 特殊功能  应用级防火墙 2 系统开启的服务查看 top,ps 命令 3 查看系统启动的服务 1) 找到目前系统开启的网络服务 n ...

  4. 重识linux-守护进程,系统服务,daemons

    重识linux-守护进程,系统服务,daemons 1分类 分为 单独的守护进程 和超级守护进程 2命名 服务的名称被创建之后,被挂上linux使用,通常在服务的名称之后会加上一个d,例如at和cro ...

  5. 重识linux-常见压缩和解压缩命令

    重识linux-常见压缩和解压缩命令 1 compress 目前已经很少使用,知道有个  不重点学习 2 gzip和zcat 目前应用最广泛 gzip [-cdtv#] 文件名 zcat 文件名.gz ...

  6. 重识linux-关于selinux

    重识linux-关于selinux 1 selinux是一个内核模块,有美国国家安全局研发,主要在基因redhat分支的系统上实现,当初的设计是未了避免用户资源的误用, 而SELINUX使用的是MAC ...

  7. 重识linux-循环执行的例行性工作调度

    重识linux-循环执行的例行性工作调度 1 用户的设置 1)/etc/cron.allow  可以使用的账号,在这个文件内 2)/etc/cron.deny 不可以的放在这个文件里面 allow的优 ...

  8. 重识linux-仅执行一次的工作调动at

    重识linux-仅执行一次的工作调动at 使用的是at命令 1 在系统中使用的是 atd这个服务 默认是不开启的 先启动 atd start 查看atd的状态 service atd status 2 ...

  9. 重识linux-linux的新增与删除用户组和切换命令

    重识linux-linux的新增与删除用户组 1 相关文件 /etc/group /etc/gshadow 2操作相关 groupadd group1 groupmod group1 groupdel ...

  10. 重识linux-linux的账号与用户组

    重识linux-linux的账号与用户组 1 账号 每个登录linux系统的用户都有 uid和gid uid就是用户ID,gid就是组ID 在系统上存账号信息的文件是 /etc/passwd 存密码相 ...

随机推荐

  1. CentOS yum 安装node.js

    第一步: curl --silent --location https://rpm.nodesource.com/setup_10.x | sudo bash - 第二步: sudo yum -y i ...

  2. mysql 迁移数据

    一.导出导入所有数据库的数据 1.导出 mysqldump -u root -p123456 --all-databases > all.sql 2.导入 mysql -u root -p123 ...

  3. ED3 flash 、OBP flash

    海力士.东芝等ED3 NAND Flash ED3的TLC编程规则相对于OBP来讲会简单许多,因为ED3的编程规则非常有规律,很容易掌握,ED3的每个WL页数量是固定的. ED3在对行地址的定义上与O ...

  4. 聊一聊 Django 中间件

    Django默认的Middleware有七个: MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.cont ...

  5. 爬虫——请求库之selenium模块

      阅读目录 一 介绍 二 安装 三 基本使用 四 选择器 五 等待元素被加载 六 元素交互操作 七 其他 八 项目练习 一 介绍 selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解 ...

  6. Druid出现DruidDataSource - recyle error - recyle error java.lang.InterruptedException: null异常排查与解决

    一.问题回顾 线上的代码之前运行的都很平稳,突然就出现了一个很奇怪的问题,看错误信息是第三方框架Druid报出来了,连接池回收连接时出现的问题. 2018-05-14 20:01:32.810 ERR ...

  7. 斐迅面试记录—SSL和TLS的区别

    SSL 是洋文“Secure Sockets Layer”的缩写,中文叫做“安全套接层”.它是在上世纪90年代中期,由网景公司设计的.(顺便插一句,网景公司不光发明了 SSL,还发明了很多 Web 的 ...

  8. cdoj1587 失恋772002天

    地址:http://acm.uestc.edu.cn/#/problem/show/1587 题目: 失恋772002天 Time Limit: 3000/1000MS (Java/Others)   ...

  9. maven install jdk版本自动降为1.7

    开发过程中遇到了一个奇怪的现象. IDEA中所有的设置都改成了1.8,但是在执行maven install时却自动降为1.7,报错提示: [ERROR] Failed to execute goal ...

  10. TOSCA自动化测试工具--怎么写自动化用例

    1.查看一下要测试的对象属性 2.