Gym
来源:互联网 发布:淘宝网吧二手电脑 编辑:程序博客网 时间:2024/06/05 02:10
http://codeforces.com/gym/101550/attachments
如图所示。
每次染色,然后问你联通块数有多少。
直接看图就行。
思路:比赛的时候想出来了,但是时间不够了,写了一个开头,本来是写对了,但是我看错了坐标,感觉很麻烦就没写。。
离线处理,然后先记录最后一个的联通块数(有一个空块就+1,联通一次就-1.这样就能得到联通块数)然后依次减去以前的操作,再次统计。
错的地方:① 我把他们都变成了一维表,因为我不太会二维并查集并且我感觉那样很慢。。但是有一个地方要注意,下面会画图说。
② 这道题的坐标很魔性。。
绿色这一排,不可以-1,红色这一排不可以+1,(摔啊,直接用一个二维数组存,然后并查的时候用一维不就好了么。用二维的方向坐标就没这么多事了qwq)
#include <bits/stdc++.h>using namespace std;/* 暴力维护。离线处理。*/const int maxn=1e6+5000;struct Node{ int x,y; int x2,y2; Node(int a,int b,int c,int d){ x=a; y=b; x2=c; y2=d; }};stack<Node>q;stack<int>pp;int num[maxn];int m,n,q1;int a,b,c,d;int fa[maxn];int cost[4];int find2(int x){ if(x==fa[x]) return x; return fa[x]=find2(fa[x]);}int ans;bool merge2(int x,int y){ if(x<0||y<0||x>=m*n||y>=m*n) return false; int a=find2(x); int b=find2(y); if(a==b) return false; fa[a]=b; //cout<<"change"<<a<<" "<<b<<"????????"<<x<<" "<<y<<endl; ans--; return true;}int main(){ scanf("%d%d%d",&m,&n,&q1); cost[0]=1; cost[1]=-1; cost[2]=n; cost[3]=-n; for(int i=0;i<m*n;i++){ fa[i]=i; } for(int i=0;i<q1;i++){ scanf("%d%d%d%d",&a,&b,&c,&d); a--,b--,c--,d--; swap(a,b);swap(c,d); if(a==c){ if(b>d) swap(b,d); for(int j=b;j<=d;j++) num[j*n+a]++; } else if(b==d){ if(a>c) swap(a,c); for(int j=a;j<=c;j++){ num[b*n+j]++; } } q.push(Node(a,b,c,d)); } ans=0; for(int i=0;i<m*n;i++){ if(!num[i]){ //cout<<num[i]<<" "<<i<<endl; ans++; for(int j=0;j<4;j++){ if(j==0&&(i%n==(n-1))) continue; if(j==1&&i%n==0) continue; if(!num[i]&&!num[i+cost[j]]) { merge2(i,i+cost[j]); } } } } //cout<<ans<<"!!"<<endl; pp.push(ans); while(!q.empty()){ Node u=q.top(); q.pop(); a=u.x; b=u.y; c=u.x2; d=u.y2; //cout<<a<<"????"<<b<<c<<d<<endl; if(a==c){ if(b>d) swap(b,d); for(int j=b;j<=d;j++){ num[j*n+a]--; int t=j*n+a; if(!num[t]) {ans++; //cout<<t<<"!!!"<<endl; for(int j=0;j<4;j++){ if(j==0&&t%(n)==(n-1)) continue; if(j==1&&t%n==0) continue; if(!num[t]&&!num[t+cost[j]]){ merge2(t,t+cost[j]); } } } } } else if(b==d){ if(a>c) swap(a,c); for(int j=a;j<=c;j++){ num[b*n+j]--; int tt=b*n+j; if(!num[tt]) ans++; for(int j=0;j<4;j++){ if(j==0&&tt%(n)==(n-1)) continue; if(j==1&&tt%n==0) continue; if(!num[tt]&&!num[tt+cost[j]]){ merge2(tt,tt+cost[j]); } } } } pp.push(ans); } pp.pop(); while(!pp.empty()){ printf("%d\n",pp.top()); pp.pop(); } return 0;}
阅读全文
0 0
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- Gym
- 从“穷逼VIP”论注释规范,你见过哪些奇葩的注释?
- 机器学习降维算法一:PCA(主成分分析算法)
- 最大熵阈值分割
- python-函数
- [NOIP2017普及组]跳房子
- Gym
- 通过例子学习spark rdd--Transformations函数
- word下载文档打不开原因
- 组合属性动画:缩放、渐变 平移和旋转+ImageLoader加载图片+MVP+OKhttp+拦截器+请求网络数据二级列表购物车
- NPOI设置Excel下拉选项
- Git常见命令总结
- 欢迎使用CSDN-markdown编辑器
- 小小的IP,大大的耦合,你痛过吗?
- 订单中心,究竟是分还是合?