zoukankan      html  css  js  c++  java
  • 1453: [Wc]Dface双面棋盘 (线段树+并茶几)

    Description

    Input

    Output

    Sample Input


    Sample Output


    HINT

     
     
      1 /*
      2     线段树+并查集维护
      3     线段树维护每列的信息 
      4     le 代表区间左端一列连通性的信息 
      5     ri 代表区间右端一列连通性的信息
      6     w,b 分别代表白色连通块和黑色连通块的个数
      7     lb 代表区间左端一列黑白点的信息 
      8     rb 代表区间右端一列黑白点的信息
      9     tmp用来暂时存储连通块个数 
     10 */
     11 #include<cstdio>
     12 #include<cstring>
     13 #include<iostream>
     14 #include<algorithm>
     15 #define MAXN 210
     16 
     17 using namespace std;
     18 
     19 struct node {
     20     int l,r;
     21     int w,b;
     22     int le[MAXN],ri[MAXN];
     23     int lb[MAXN],rb[MAXN];
     24 };
     25 node t[MAXN<<2];
     26 
     27 int a[MAXN][MAXN],n,m;
     28 
     29 int fa[MAXN<<2],tmp[MAXN<<2];
     30 
     31 inline void read(int&x) { 
     32     int f=1;x=0;char c=getchar(); 
     33     while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();} 
     34     while(c>='0'&&c<='9') {x=(x<<1)+(x<<3)+c-48;c=getchar();} 
     35     x=x*f; 
     36 } 
     37 
     38 inline int find(int x) {
     39     if(x==fa[x]) return fa[x];
     40     else return fa[x]=find(fa[x]);
     41 }
     42 
     43 inline void up(int now) {
     44     t[now].w=t[now<<1].w+t[now*2+1].w;
     45     t[now].b=t[now<<1].b+t[now*2+1].b;
     46     memcpy(t[now].lb,t[now<<1].lb,sizeof t[now].lb);
     47     memcpy(t[now].rb,t[now*2+1].rb,sizeof t[now].rb);
     48     for(int i=1;i<=3*n;i++) fa[i]=i;
     49     for(int i=1;i<=n;i++) 
     50       t[now*2+1].le[i]+=2*n,t[now*2+1].ri[i]+=2*n;
     51     for(int i=1;i<=n;i++) {
     52         int x=t[now<<1].ri[i],y=t[now*2+1].le[i];
     53             if(find(x)!=find(y)&&t[now<<1].rb[i]==t[now*2+1].lb[i]) {
     54             fa[find(x)]=find(y);
     55             if(t[now<<1].rb[i]) t[now].b--;
     56             else t[now].w--;
     57         }
     58     }
     59     for(int i=1;i<=n;i++) 
     60       t[now].le[i]=find(t[now<<1].le[i]),t[now].ri[i]=find(t[now*2+1].ri[i]);
     61     for(int i=1;i<=n;i++) 
     62       tmp[i<<1]=t[now].le[i],tmp[(i<<1)-1]=t[now].ri[i];
     63     sort(tmp+1,tmp+1+2*n);
     64     int maxdata=unique(tmp+1,tmp+1+2*n)-tmp-1;
     65     for(int i=1;i<=n;i++)
     66       t[now].le[i]=lower_bound(tmp+1,tmp+1+maxdata,t[now].le[i])-tmp,t[now].ri[i]=lower_bound(tmp+1,tmp+1+maxdata,t[now].ri[i])-tmp;
     67     for(int i=1;i<=n;i++) t[now*2+1].le[i]-=2*n,t[now*2+1].ri[i]-=2*n;
     68     return;
     69 }
     70 
     71 void build_tree(int now,int l,int r) {
     72     t[now].l=l;
     73     t[now].r=r;
     74     if(l==r) {
     75         int tot=0;
     76         for(int i=1;i<=n;i++) {
     77             if(a[i][l]!=a[i-1][l]) {
     78                 tot++;
     79                 if(a[i][l]) t[now].b++;
     80                 else t[now].w++;
     81             }
     82             t[now].le[i]=t[now].ri[i]=tot;
     83             t[now].lb[i]=t[now].rb[i]=a[i][l];
     84         }
     85         return;
     86     }
     87     int mid=(l+r)>>1;
     88     build_tree(now<<1,l,mid);
     89     build_tree(now*2+1,mid+1,r);
     90     up(now);
     91 }
     92 
     93 void modify(int now,int pos) {
     94     if(t[now].l==t[now].r) {
     95         int tot=0;
     96         t[now].b=0;
     97         t[now].w=0;
     98         for(int i=1;i<=n;i++) {
     99             if(a[i][pos]!=a[i-1][pos]) {
    100                 tot++;
    101                 if(a[i][pos]) t[now].b++;
    102                 else t[now].w++;
    103             }
    104             t[now].le[i]=t[now].ri[i]=tot;
    105             t[now].lb[i]=t[now].rb[i]=a[i][pos];
    106         }
    107         return;
    108     }
    109     int mid=(t[now].l+t[now].r)>>1;
    110     if(pos<=mid) modify(now<<1,pos);
    111     else modify(now*2+1,pos);
    112     up(now);
    113 }
    114 
    115 int main() {
    116     read(n);
    117     for(int i=1;i<=n;i++) {
    118         a[0][i]=-1;
    119         for(int j=1;j<=n;j++)
    120           read(a[i][j]);
    121     }
    122     build_tree(1,1,n);
    123     read(m);
    124     for(int i=1;i<=m;i++) {
    125         int x,y;
    126         read(x);read(y);
    127         a[x][y]^=1;
    128         modify(1,y);
    129         printf("%d %d
    ",t[1].b,t[1].w);
    130     }
    131     return 0;
    132 }
    题解


    作者:乌鸦坐飞机
    出处:http://www.cnblogs.com/whistle13326/
    新的风暴已经出现 怎么能够停止不前 穿越时空 竭尽全力 我会来到你身边 微笑面对危险 梦想成真不会遥远 鼓起勇气 坚定向前 奇迹一定会出现

     
  • 相关阅读:
    点击标签,通过jquery.jcarousel动态axaj加载内容,实现跑马灯效果
    FreeSwitch VoiceMail 语音信箱 研究
    FreeSwitch IVR VoiceMail 语音信箱
    微软企业库连接access,web.config相对路径配置
    FreeSWITCH 添加中文语音包
    FreeSwitch通过远程接口返回动态IVR语音菜单
    FreeSwitch注册上了,但拨打电话,提示Rejcted by acl "domians". Falling back to Digest auth
    ACM:密码截获
    c++ ACM:递归实例
    CSS:浏览器兼容性图表
  • 原文地址:https://www.cnblogs.com/whistle13326/p/7308206.html
Copyright © 2011-2022 走看看