• (线段树+并查集) Codeforces Round #416 (Div. 2) E Vladik and Entertaining Flags


    In his spare time Vladik estimates beauty of the flags.

    Every flag could be represented as the matrix n × m which consists of positive integers.

    Let's define the beauty of the flag as number of components in its matrix. We call component a set of cells with same numbers and between any pair of cells from that set there exists a path through adjacent cells from same component. Here is the example of the partitioning some flag matrix into components:

    But this time he decided to change something in the process. Now he wants to estimate not the entire flag, but some segment. Segment of flag can be described as a submatrix of the flag matrix with opposite corners at (1, l) and (n, r), where conditions 1 ≤ l ≤ r ≤ m are satisfied.

    Help Vladik to calculate the beauty for some segments of the given flag.

    Input

    First line contains three space-separated integers nmq (1 ≤ n ≤ 10, 1 ≤ m, q ≤ 105) — dimensions of flag matrix and number of segments respectively.

    Each of next n lines contains m space-separated integers — description of flag matrix. All elements of flag matrix is positive integers not exceeding 106.

    Each of next q lines contains two space-separated integers lr (1 ≤ l ≤ r ≤ m) — borders of segment which beauty Vladik wants to know.

    Output

    For each segment print the result on the corresponding line.

    Example

    Input
    4 5 4
    1 1 1 1 1
    1 2 2 3 3
    1 1 1 2 5
    4 4 5 5 5
    1 5
    2 5
    1 2
    4 5
    Output
    6
    7
    3
    4

    Note

    Partitioning on components for every segment from first test case:

    线段树维护每个矩形边缘的情况,合并时利用并查集。

      1 #include <iostream>
      2 #include <string>
      3 #include <algorithm>
      4 #include <cstring>
      5 #include <cstdio>
      6 #include <cmath>
      7 #include <queue>
      8 #include <set>
      9 #include <map>
     10 #include <list>
     11 #include <vector>
     12 #include <stack>
     13 #define mp make_pair
     14 #define MIN(a,b) (a>b?b:a)
     15 #define rank rankk
     16 //#define MAX(a,b) (a>b?a:b)
     17 typedef long long ll;
     18 typedef unsigned long long ull;
     19 const int MAX=1e5+5;
     20 const ll INF=9223372036854775807;
     21 const int N=12;
     22 using namespace std;
     23 const int MOD=1e9+7;
     24 typedef pair<int,int> pii;
     25 const double eps=0.000000001;
     26 int par[MAX];
     27 int a[N][MAX];
     28 int n,m,q;
     29 int id[N<<1];
     30 int find(int x)
     31 {
     32     if(x==par[x])
     33         return x;
     34     return par[x]=find(par[x]);
     35 }
     36 void unite(int x,int y)
     37 {
     38     x=find(x);y=find(y);
     39     par[x]=y;
     40 }
     41 bool same(int x,int y)
     42 {
     43     return find(x)==find(y);
     44 }
     45 struct node
     46 {
     47     int l[N],r[N],sum;//l值在[1,n],r的值在[n+1,2n]
     48 }b[MAX<<2];
     49 void merge(node &lson,node &rson,node &rt,int lright,int rleft)
     50 {
     51     rt.sum=lson.sum+rson.sum;
     52     for(int i=1;i<=n;i++)
     53     {
     54         par[i]=lson.l[i];
     55         par[i+n]=lson.r[i];
     56         par[i+2*n]=rson.l[i]+2*n;
     57         par[i+3*n]=rson.r[i]+2*n;
     58     }
     59     for(int i=1;i<=n;i++)
     60     {
     61         if(a[i][lright]==a[i][rleft]&&!same(i+n,i+2*n))
     62         {
     63             --rt.sum;
     64             unite(i+n,i+2*n);
     65         }
     66     }
     67     for(int i=1;i<=4*n;i++)
     68     {
     69         par[i]=find(par[i]);
     70         id[par[i]]=-1;
     71     }
     72     for(int i=1;i<=n;i++)
     73     {
     74         if(id[par[i]]==-1)
     75             id[par[i]]=i;
     76         rt.l[i]=id[par[i]];
     77     }
     78     for(int i=3*n+1;i<=4*n;i++)
     79     {
     80         if(id[par[i]]==-1)
     81             id[par[i]]=i-2*n;
     82         rt.r[i-3*n]=id[par[i]];
     83     }
     84 }
     85 void build(int l,int r,int k)
     86 {
     87     if(l==r)
     88     {
     89         b[k].sum=0;
     90         for(int i=1;i<=n;i++)
     91         {
     92             if(i==1||a[i-1][l]!=a[i][l])
     93             {
     94                 b[k].l[i]=b[k].r[i]=i;
     95                 ++b[k].sum;
     96             }
     97             else
     98                 b[k].l[i]=b[k].r[i]=b[k].l[i-1];
     99         }
    100         return ;
    101     }
    102     int mid=(l+r)/2;
    103     build(l,mid,2*k);
    104     build(mid+1,r,2*k+1);
    105     merge(b[2*k],b[2*k+1],b[k],mid,mid+1);
    106 }
    107 void query(int ql,int qr,int l,int r,int k,node &ans)
    108 {
    109     if(l>=ql&&r<=qr)
    110     {
    111         ans=b[k];return;
    112     }
    113     int mid=(l+r)/2;
    114     if(qr<=mid)
    115         query(ql,qr,l,mid,2*k,ans);
    116     else if(ql>mid)
    117         query(ql,qr,mid+1,r,2*k+1,ans);
    118     else
    119     {
    120         node p,q;
    121         query(ql,qr,l,mid,2*k,p);
    122         query(ql,qr,mid+1,r,2*k+1,q);
    123         merge(p,q,ans,mid,mid+1);
    124     }
    125 }
    126 int main()
    127 {
    128     int qs;
    129     scanf("%d%d%d",&n,&m,&qs);
    130     for(int i=1;i<=n;i++)
    131         for(int j=1;j<=m;j++)
    132             scanf("%d",&a[i][j]);
    133     build(1,m,1);
    134     node an;
    135     int i;
    136     for(i=1;i<=qs;i++)
    137     {
    138         int ls,rs;
    139         scanf("%d%d",&ls,&rs);
    140         query(ls,rs,1,m,1,an);
    141         printf("%d
    ",an.sum);
    142     }
    143     return 0;
    144 }
  • 相关阅读:
    docker容器跑tomcat遇到的坑
    PCL 编程多个点云合成
    PCL 常用小知识
    PCL点云库中的坐标系(CoordinateSystem)
    Ubuntu14.04(64位)下gcc-linaro-arm-linux-gnueabihf交叉编译环境搭建
    Windows cmd 快捷操作
    #Pragma Pack与内存分配
    线段上的整数点个数
    基于PCL绘制模型并渲染
    rosbag数据记录及转换图片、视频
  • 原文地址:https://www.cnblogs.com/quintessence/p/6919227.html
Copyright © 2020-2023  润新知