离线LCT维护MST,和3082的方法一样。然而比较码农,适合颓废的时候写。

PS:线段树分治要好写得多,LCT比较自娱自乐。

#include<bits/stdc++.h>
using namespace std;
const int dx[]={-1,1,0,0};
const int dy[]={0,0,-1,1};
const int inf=1e9;
int n;
int cal1(int x1,int y1,int x2,int y2){
int i=(min(x1,x2)*n+min(y1,y2))*2;
return x1==x2?i:i+1;
}
struct node;
typedef node*ptr;
struct vec{
int v;ptr i,s,t;
vec(){v=inf;}
};
bool operator<(vec a,vec b){
return a.v<b.v;
}
struct node{
ptr i,j,p;bool r;vec v,s;
node();
ptr up(){
s=min(min(v,i->s),j->s);
return this;
}
void down(){
if(r)
i->r^=1,j->r^=1,swap(i,j),r=0;
}
}e[120000];
node::node(){i=j=p=e;}
bool root(ptr o){
return o!=o->p->i&&o!=o->p->j;
}
void turn(ptr o){
ptr s=o->p,t=s->p;
if(!root(s))(s==t->i?t->i:t->j)=o;
o->p=t,s->p=o;
if(o==s->i)
s->i=o->j,o->j->p=s,o->j=s->up();
else
s->j=o->i,o->i->p=s,o->i=s->up();
}
void push(ptr o){
if(!root(o))push(o->p);
o->down();
}
ptr splay(ptr o){
push(o);
while(!root(o)){
if(!root(o->p))turn(o==o->p->i^o->p==o->p->p->i?o:o->p);
turn(o);
}
return o->up();
}
ptr exp(ptr o){
ptr s=e;
while(o!=e)splay(o)->j=s,s=o->up(),o=o->p;
return s;
}
ptr bel(ptr o){
o=exp(o);
while(o->i!=e)o=o->i,o->down();
return o;
}
bool jud(ptr s,ptr t){
exp(s)->r=1;
return bel(t)==s;
}
void link(ptr s,ptr t){
exp(s)->r=1,splay(s)->p=t;
}
bool cut(ptr s,ptr t){
exp(s)->r=1,exp(t);
splay(t);
if(s==t->i&&s->j==e)
return t->i=s->p=e;
return 0;
}
ptr cal2(int i){
return e+n*n+i+1;
}
bool link(int x1,int y1,int x2,int y2){
ptr s=e+x1*n+y1+1;
ptr t=e+x2*n+y2+1;
int i=cal1(x1,y1,x2,y2);
if(!jud(s,t)){
link(s,cal2(i));
link(t,cal2(i));
return 1;
}
exp(s)->r=1;
vec v=exp(t)->s;
if(v<cal2(i)->v){
cut(v.s,v.i);
cut(v.t,v.i);
link(s,cal2(i));
link(t,cal2(i));
}
return 0;
}
bool cut(int x1,int y1,int x2,int y2){
ptr s=e+x1*n+y1+1;
ptr t=e+x2*n+y2+1;
int i=cal1(x1,y1,x2,y2);
if(cut(s,cal2(i)))
return cut(t,cal2(i));
return 0;
}
int m,t,c6[2],c1[200][200];
queue<int>c3[80000];
void pre(int x1,int y1,int x2,int y2){
if(!~x1||x1==n||!~y1||y1==n||!~x2||x2==n||!~y2||y2==n)
return;
int i=cal1(x1,y1,x2,y2);
if(c1[x1][y1]==c1[x2][y2])
c3[i].push(t);
}
void ins(int x1,int y1,int x2,int y2){
if(!~x1||x1==n||!~y1||y1==n||!~x2||x2==n||!~y2||y2==n)
return;
int i=cal1(x1,y1,x2,y2);
if(c1[x1][y1]==c1[x2][y2]){
cal2(i)->v.i=cal2(i);
cal2(i)->v.s=e+x1*n+y1+1;
cal2(i)->v.t=e+x2*n+y2+1;
if(c3[i].empty())
cal2(i)->v.v=inf;
else{
cal2(i)->v.v=c3[i].front();
c3[i].pop();
}
if(link(x1,y1,x2,y2))
--c6[c1[x1][y1]];
}
}
void del(int x1,int y1,int x2,int y2){
if(0<=x1&&x1<n&&0<=y1&&y1<n&&0<=x2&&x2<n&&0<=y2&&y2<n&&c1[x1][y1]==c1[x2][y2]&&cut(x1,y1,x2,y2))
++c6[c1[x1][y1]];
}
struct que{int x,y;};
que c2[10000];
int main(){
struct{
operator int(){
int x=0,c=getchar();
while(c<48)c=getchar();
while(c>32)
x=x*10+c-48,c=getchar();
return x;
}
}it;
n=it;
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
++c6[c1[i][j]=it];
m=it;
for(int&i=t=0;i<m;++i){
int x=it-1,y=it-1;
c2[i].x=x,c2[i].y=y;
for(int j=0;j<4;++j)
pre(x,y,x+dx[j],y+dy[j]);
c1[x][y]^=1;
}
for(int i=m-1;~i;--i)
c1[c2[i].x][c2[i].y]^=1;
for(int i=0;i<n;++i)
for(int j=0;j<n;++j){
ins(i,j,i,j+1);
ins(i,j,i+1,j);
}
for(int i=0;i<m;++i){
int x=c2[i].x,y=c2[i].y;
for(int j=0;j<4;++j)
del(x,y,x+dx[j],y+dy[j]);
--c6[c1[x][y]];
++c6[c1[x][y]^=1];
for(int j=0;j<4;++j)
ins(x,y,x+dx[j],y+dy[j]);
printf("%d %d\n",c6[1],c6[0]);
}
}

BZOJ1453: [WC2005]Dface双面棋盘的更多相关文章

  1. BZOJ1453: [Wc]Dface双面棋盘

    Description Input Output Sample Input Sample Output HINT 线段树套并查集应该是比较好写的做法,时间复杂度为O(N^3+M*NlogN). #in ...

  2. 【BZOJ1453】[Wc]Dface双面棋盘 线段树+并查集

    [BZOJ1453][Wc]Dface双面棋盘 Description Input Output Sample Input Sample Output HINT 题解:话说看到题的第一反应其实是LCT ...

  3. bzoj 1453: [Wc]Dface双面棋盘

    1453: [Wc]Dface双面棋盘 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 617  Solved: 317[Submit][Status][ ...

  4. 【BZOJ1453】[WC] Dface双面棋盘(LCT维护联通块个数)

    点此看题面 大致题意: 给你一个\(n*n\)的黑白棋盘,每次将一个格子翻转,分别求黑色连通块和白色连通块的个数. \(LCT\)动态维护图连通性 关于这一部分内容,可以参考这道例题:[BZOJ402 ...

  5. BZOJ1453:[WC]Dface双面棋盘

    浅谈树状数组与线段树:https://www.cnblogs.com/AKMer/p/9946944.html 题目传送门:https://lydsy.com/JudgeOnline/problem. ...

  6. [BZOJ1453]Dface双面棋盘

    Description Input Output Sample Input Sample Output HINT 线段树+并查集,暴力记录和更新一些信息,详情见代码注解. #include<cm ...

  7. [Wc]Dface双面棋盘()

    题解: 一道维护奇怪信息的线段树... 我刚开始看了标签想的是删去图上一个点后求连通性 发现不会 于是退化成一般图支持删除 插入 维护连通性 发现有2两种做法 1.lct维护 按照结束顺序先后排序,给 ...

  8. 【刷题】BZOJ 1453 [Wc]Dface双面棋盘

    Description Input Output Sample Input Sample Output HINT Solution 不强制在线的动态图问题,那就LCT了 类似二分图那道题目 对于四个方 ...

  9. P4121 [WC2005]双面棋盘

    题目 P4121 [WC2005]双面棋盘 貌似是刘汝佳出的题目?? 做法 线段树维护并查集 线段树分治\(1\)~\(n\)行,我们要考虑维护的肯定是黑.白各自的联通块数量 考虑区间合并,其实就与中 ...

随机推荐

  1. LeetCode OJ--Implement strStr()

    http://oj.leetcode.com/problems/implement-strstr/ 判断一个串是否为另一个串的子串 比较简单的方法,复杂度为O(m*n),另外还可以用KMP时间复杂度为 ...

  2. codeforces #472(div 1)

    B(two point) 题意: 给出长度为n的非递减数组E[1..n],对于所有三元组(i,j,k),1<=i<j<k<=n且Ek-Ei<=U,我们需要计算出最大的(E ...

  3. NOIP前必须记住的30句话

    NOIP前必须记住的30句话 1.比赛前一天晚上请准备好你的各种证件,事先查好去往考场的路线2.比赛之前请先调整你的屏幕分辨率到你喜欢的大小3.比赛之前请把编译器的字体调为你平时惯用的字体,尤其是注意 ...

  4. Ionic 学习笔记

    本文为原创,转载请注明出处: cnzt       文章:cnzt-p http://www.cnblogs.com/zt-blog/p/7831153.html 注: 本篇学习笔记基于Ionic 3 ...

  5. 创建注记图层C# IFeatureWorkspaceAnno

    http://blog.csdn.net/mydriverc/article/details/1675613     //IFeatureWorkspaceAnno Example     //The ...

  6. hdu2204Eddy&#39;s爱好

    大概题意是要你输出1到n中,可以表示成a^b的数,a,b都是大于0的整数的个数, 当中b大于1. 由于1到n中.可以全然开平方的个数就是(n^0.5)的整数部分. 以此类推能够得到,全然开立方.全然开 ...

  7. BUPT复试专题—众数(2014)

    题目描述 有一个长度为N的非降数列,求数列中出现最多的数,若答案不唯一输出最小的数 输入 第一行T表示测试数据的组数(T<100) 对于每组测试数据: 第一行是一个正整数N表示数列长度 第二行有 ...

  8. Solidworks工程图 如何绘制向视图,辅助视图

    先画一条垂直于视野方向的中心线   点击辅助视图,然后点选刚才的中心线即可生成向视图   对向视图的标准可以得到一些用其他方法不好标注的尺寸            

  9. js中对arry数组的各种操作小结 瀑布流AJAX无刷新加载数据列表--当页面滚动到Id时再继续加载数据 web前端url传递值 js加密解密 HTML中让表单input等文本框为只读不可编辑的方法 js监听用户的键盘敲击事件,兼容各大主流浏览器 HTML特殊字符

    js中对arry数组的各种操作小结   最近工作比较轻松,于是就花时间从头到尾的对js进行了详细的学习和复习,在看书的过程中,发现自己平时在做项目的过程中有很多地方想得不过全面,写的不够合理,所以说啊 ...

  10. WPF窗口最大化

    做C/S应用程序的过程中,要实现的一个功能是可以编辑系统某一类表,这些表又含有不同的properties,properties数量也不相同,有二十来个的,也有一两个的,所以,popUp出来之后大小各异 ...