zoukankan      html  css  js  c++  java
  • 一维黑白棋

    一维黑白棋(jdoj-2189)

        题目大意:给你一个$1cdot n$的棋盘,开始都是白色,每次操作是将区间 [ L , R ] 之间的棋子染黑,染m次,求解每次的战况:黑子个数与白子个数。

        注释:1<=L<=R<=n<=$2cdot 10^5$,1<=m<=$2cdot 10^5$。

          想法:这题暴力显然过不去,而且是一个区间修改,区间查询,可以考虑用线段树维护。但是....那不就成傻题了吗!!在此,介绍一种lijinnn神犇讲的做法(博主仅限于听懂)。我们可以考虑用并查集维护:每一个棋子x的father是它右侧第一个白子(包括自己)。那么,维护一个指针,每次修改从L开始,如果是白子,将其染黑,指针++;如果是黑子,指针直接指向它的father,这个黑子的father在指针走了之后修改为R+1,这样就可以在log的时间复杂度内完成修改。这道题就做完了。此题是容易的,但这其中蕴含的是对并查集极其深刻的理解,在此鸣谢lijinnn。

        最后,附上帅气的代码(lijinnn在旁指导)......

     1 #include <iostream>
     2 #include <cstdio>
     3 using namespace std;
     4 int fa[200010];
     5 int find(int x)
     6 {
     7     if(x==fa[x]) return x;
     8     else return fa[x]=find(fa[x]);
     9 }
    10 int main()
    11 {
    12     int l,r;
    13     int n,m;
    14     scanf("%d%d",&n,&m);
    15     for(int i=1;i<=n+1;i++) fa[i]=i;
    16     int ans=n;
    17     while(m--)
    18     {
    19         scanf("%d%d",&l,&r);
    20         int x=l;
    21         while(1)
    22         {
    23             x=find(x);
    24             if(x<=r)
    25             {
    26                 ans--;
    27                 fa[x]=r+1;
    28                 x++;
    29             }
    30             else
    31             {
    32                 printf("%d %d
    ",n-ans,ans);
    33                 break;
    34             }
    35         }
    36     }
    37     return 0;
    38 }

        小结:错误:

        1.如果是黑子是,我将它的father设成x+1了,果断Gg

       转载请注明:http://www.cnblogs.com/ShuraK/p/7894500.html——未经博主允许,严禁转载

  • 相关阅读:
    html中滚动条的样式
    在个人机上发布web项目
    Apache与SVN的集成
    待完成
    chmod
    【转】ubuntu修改IP地址和网关的方法
    ubuntu 添加svn服务
    生成指定大小的空文件
    数码单反相机完全攻略
    【转】ubuntu subversion安装
  • 原文地址:https://www.cnblogs.com/ShuraK/p/7894500.html
Copyright © 2011-2022 走看看