• LA_4730 Kingdom 并查集+树状数组


    给定N个点的坐标,代表N各城市,有M种操作,共分两种,一种是连线,把两个点连起来(一旦构成连通图,这个连通图即为一个州),还有种询问操作,为y=c,(c为小数部分恒为.5的实数),问y=c这条线经过了多少个大周,这些州总共有多少个城市

    很明显要用到并查集,比较好的做法是把并查集落实到线段树上,并查集维护的是每个集合的最大y和最小y,以及rank表示集合数目。但是线段树要用到离散化、

    然后参照一个用树状数组的博客,其实思路差不多,都是把每次的变更落实到树上

    不过这个树状数组跟之前写的不一样,这个是改段查点型的,之前的是改点查段型的,其实只要改一下辅助数组的定义即可,在这个树状数组里面,把辅助数组d当做从1到当前所有的变更,每次更新时从当前往递减方向,所以,为了得到某个点值,必须把当前点以及当前之前的变更都加起来。

    所以这个

    add(int loc,int v)

    {

        while (loc>0){d[loc]+=v;loc-=lowbit(loc);}

    }

    query(int loc)

    {

       int ret=0;

       while (loc<n) {ret+=d[loc];loc+=lowbit(loc);}

       return ret;

    }

    因为给定的数是.5的实数,故意把坐标往后压一位即可,把每一个小格子往后压成一个点即可

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 using namespace std;
      6 
      7 int n,m;
      8 int f[100010],rank[100010],y1[100010],y2[100010];
      9 void init()
     10 {
     11     for (int i=0;i<=n;i++){
     12         f[i]=i;
     13         rank[i]=1;
     14     }
     15 }
     16 int findset(int x)
     17 {
     18     if (x!=f[x]){
     19         f[x]=findset(f[x]);
     20     }
     21     return f[x];
     22 }
     23 int lowbit(int x)
     24 {
     25     return x&(-x);
     26 }
     27 struct bit
     28 {
     29     int d[100010];
     30     int limit;
     31     void clear()
     32     {
     33         memset(d,0,sizeof d);
     34     }
     35     void add(int L,int R,int v){
     36         while (R>=1){
     37             d[R]+=v;
     38             R-=lowbit(R);
     39         }
     40         while (L>=1){
     41             d[L]+=-v;
     42             L-=lowbit(L); //L这里不能算点,因为每个格子都往后压,每个点x,就代表x-1到x这个区间,所以在这里可以抵消L的格子的影响
     43         }
     44     }
     45     int query(int x)
     46     {
     47         int ret=0;
     48         while (x<=limit){
     49             ret+=d[x];
     50             x+=lowbit(x);
     51         }
     52         return ret;
     53     }
     54 }city,state;
     55 void unit(int r1,int r2)
     56 {
     57     f[r1]=r2;
     58     rank[r2]+=rank[r1];
     59 }
     60 int main()
     61 {
     62     int t;
     63     scanf("%d",&t);
     64     int a,b;
     65     double c;
     66     char ch[10];
     67     while (t--)
     68     {
     69         city.clear();
     70         state.clear();
     71         scanf("%d",&n);
     72         init();
     73         int maxn=0;
     74         for (int i=0;i<n;i++){
     75             scanf("%d%d",&a,&b);
     76             y1[i]=b;y2[i]=b;
     77             maxn=max(maxn,b);
     78         }
     79         city.limit=state.limit=maxn;
     80         scanf("%d",&m);
     81         for (int i=1;i<=m;i++){
     82             scanf("%s",ch);
     83             if (ch[0]=='r'){
     84                 scanf("%d%d",&a,&b);
     85                 int r1=findset(a);
     86                 int r2=findset(b);
     87                 if (r1==r2) continue;
     88                 if (rank[r1]==1 && rank[r2]==1){
     89                     unit(r1,r2);
     90                     y1[r2]=min(y1[r2],y1[r1]);
     91                     y2[r2]=max(y2[r2],y2[r1]);
     92                     city.add(y1[r2],y2[r2],1);
     93                     state.add(y1[r2],y2[r2],rank[r2]);
     94                 }
     95                 else
     96                 if (rank[r1]==1 || rank[r2]==1){
     97                     if (rank[r1]==1) swap(r1,r2);
     98                     city.add(y1[r1],y2[r1],-1);
     99                     state.add(y1[r1],y2[r1],-rank[r1]);
    100                     unit(r1,r2);
    101                     y1[r2]=min(y1[r1],y1[r2]);
    102                     y2[r2]=max(y2[r1],y2[r2]);
    103                     city.add(y1[r2],y2[r2],1);
    104                     state.add(y1[r2],y2[r2],rank[r2]);
    105                 }
    106                 else
    107                 {
    108                     city.add(y1[r1],y2[r1],-1);
    109                     state.add(y1[r1],y2[r1],-rank[r1]);
    110 
    111                     city.add(y1[r2],y2[r2],-1);
    112                     state.add(y1[r2],y2[r2],-rank[r2]);
    113 
    114                     unit(r1,r2);
    115                     y1[r2]=min(y1[r1],y1[r2]);
    116                     y2[r2]=max(y2[r1],y2[r2]);
    117                     city.add(y1[r2],y2[r2],1);
    118                     state.add(y1[r2],y2[r2],rank[r2]);
    119                 }
    120             }
    121             else {
    122                 scanf("%lf",&c);
    123                 int tmp=c;
    124                 tmp++;
    125                 printf("%d %d
    ",city.query(tmp),state.query(tmp));
    126             }
    127         }
    128     }
    129     return 0;
    130 }
  • 相关阅读:
    log4j的基本配置参数
    插入透明背景Flash的HTML代码
    oracle获取字符串长度函数length()和hengthb()
    HSQLDB安装与使用
    linux下完全删除Oracle
    SQL查询前几条记录
    LINUX安装ORACLE 9204 报错解决!!
    ORACLE 归档日志打开关闭方法
    hsqldb快速入门
    Openstack中查看虚拟机console log的几种方法
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3848555.html
Copyright © 2020-2023  润新知