[APIO2011]
来自FallDream的博客,未经允许,请勿转载,谢谢。
------------------------------------------------------
A.[Apio2011]方格染色
Sam和他的妹妹Sara有一个包含n × m个方格的表格。她们想要将其的每个方格都染成红色或蓝色。出于个人喜好,他们想要表格中每个2 × 2的方形区域都包含奇数个(1 个或 3 个)红色方格。例如,右图是一个合法的表格染色方案(在打印稿中,深色代表蓝色,浅色代表红色) 。 可是昨天晚上,有人已经给表格中的一些方格染上了颜色!现在Sam和Sara非常生气。不过,他们想要知道是否可能给剩下的方格染上颜色,使得整个表格仍然满足她们的要求。如果可能的话,满足他们要求的染色方案数有多少呢? $n,m,k\leqslant 10^{6}$
题解:打表观察了一波,除了答案貌似是2的倍数,很经常是$2^{n+m-1}$以外都不懂,无奈看题解。
我们可以把限制条件当作异或关系式,(我不懂怎么打异或,就用$\veebar$ 代替吧)即对于$x>1且y>1,S[x][y]\veebar S[x][y-1]\veebar S[x-1][y]\veebar S[x-1][y-1]=1$,对于一个在$(a,b),a>1,b>1$的已经有颜色的块,我们把所有$x\leqslant a,y\leqslant b$的异或关系式塔起来,得到$Sab\veebar S[a][1]\veebar S[1][b]\veebar S[1][1]=Color(a,b)$这个式子只有在ab都是偶数的时候,才等于1。假如确定了$(1,1)$的颜色,那我们就能用一个异或方程表示第a行和第b列的关系。那我们就直接枚举$(1,1)$的颜色,通过并查集维护就可以啦。在维护的时候,如果出现矛盾,说明无解,否则假设联通块有num个,答案是$2^{num-1}$
#include<iostream>
#include<cstdio>
#define MN 1000000
#define mod 1000000000
using namespace std;
inline int read()
{
int x = , f = ; char ch = getchar();
while(ch < '' || ch > ''){ if(ch == '-') f = -; ch = getchar();}
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return x * f;
}
int n,m,k,fa[MN*+],g[MN*+],ans=;
struct limit{int x,y,z;}s[MN+]; int pow(int x,int k)
{
int sum=;
for(int i=x;k;k>>=,i=1LL*i*i%mod)
if(k&)
sum=1LL*sum*i%mod;
return sum;
} int getfa(int x)
{
if(fa[x]==x) return x;
int t=getfa(fa[x]);g[x]^=g[fa[x]];
return fa[x]=t;
} int calc()
{
for(int i=;i<=m+n;i++) fa[i]=i,g[i]=;fa[n+]=;
for(int i=;i<=k;i++)
{
if(s[i].x+s[i].y<=) continue;
int x=getfa(s[i].x),y=getfa(s[i].y+n),t=g[s[i].x]^g[s[i].y+n]^s[i].z;
if(x!=y){fa[x]=y;g[x]=t;}
else if(t) return ;
}
int num=;
for(int i=;i<=n+m;i++)
if(fa[i]==i) num++;
return pow(,num-);
} int main()
{
n=read();m=read();k=read();
bool flag[];
for(int i=;i<=k;i++)
{
s[i].x=read();s[i].y=read();s[i].z=read();
if(s[i].x+s[i].y<) flag[s[i].z]=;
if(!(s[i].x&||s[i].y&)) s[i].z^=;
}
if(!flag[]) ans+=calc();
if(!flag[])
{
for(int i=;i<=k;i++) if(s[i].x>&&s[i].y>)s[i].z^=;
ans+=calc();
}
cout<<ans%mod;
return ;
}
B.寻路
一个二维平面上有很多个矩形,你要从一个给定的点向上下左右任意方向出发,然后只能在矩形的边上或者角上转弯,问到达另一个点的最短路径。
20组数据,每组矩形数量不超过1000
题解:我们考虑最短路,直接建图最多只会有n^2个点,但是它们不全是有用的,所以我们考虑从每一个矩形的角上向四周出发连边,这样最多只有12n个点,跑最短路就行了。建图稍微复杂点。
复杂度Tnlogn
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
#define INF 20000000000000LL
#define MN 1000
#define mp(x,y) make_pair((x),(y))
#define pa pair<ll,int>
using namespace std;
inline int read()
{
int x = , f = ; char ch = getchar();
while(ch < '' || ch > ''){ if(ch == '-') f = -; ch = getchar();}
while(ch >= '' && ch <= ''){x = x * + ch - '';ch = getchar();}
return x * f;
}
int n,cnt,lcnt,cn,head[MN*];
inline int abs(int x){return x<?-x:x;}
struct L{
int l,r,x;
vector<int> s;
L(){}
L(int l,int r,int x):l(l),r(r),x(x){s.clear();}
bool operator<(const L&b)const{return x<b.x;}
}r[MN*+],c[MN*+];
struct P
{
int x,y;
P(int x=,int y=):x(x),y(y){}
friend int dis(P x,P y){return abs(x.x-y.x)+abs(x.y-y.y);}
bool operator==(const P&b)const{return x==b.x&&y==b.y;}
}p[MN*MN+];
bool cmp(int x,int y){return p[x].x==p[y].x?p[x].y<p[y].y:p[x].x<p[y].x;}
struct edge{int to,next,w;}e[MN*+];
inline void ins(int f,int t,int w){e[++cn]=(edge){t,head[f],w};head[f]=cn;};
priority_queue<pa,vector<pa>,greater<pa> > q;
ll d[MN*];bool mark[MN*]; void dij()
{
memset(d,,sizeof(d));memset(mark,,sizeof(mark));
d[]=;q.push(mp(,));
while(!q.empty())
{
int now=q.top().second;q.pop();
if(mark[now]) continue;mark[now]=;
for(int i=head[now];i;i=e[i].next)
if(d[now]+e[i].w<d[e[i].to])
{
d[e[i].to]=d[now]+e[i].w;
q.push(mp(d[e[i].to],e[i].to));
}
}
} int main()
{
int T=read();
while(T--)
{
memset(head,,sizeof(head));
cnt=lcnt=cn=;int fx=read(),fy=read(),tx=read(),ty=read();
p[++cnt]=P(fx,fy);p[++cnt]=P(tx,ty);
if(fx==tx||fy==ty) ins(,,dis(p[],p[])),ins(,,dis(p[],p[]));
n=read();
for(int i=;i<=n;i++)
{
int x1=read(),y1=read(),x2=read(),y2=read();
if(x1>x2) swap(x1,x2);if(y1>y2) swap(y1,y2);
p[++cnt]=P(x1,y1);p[++cnt]=P(x1,y2);
p[++cnt]=P(x2,y1);p[++cnt]=P(x2,y2);
c[++lcnt]=L(cnt-,cnt-,y1);r[lcnt]=L(cnt-,cnt-,x1);
c[++lcnt]=L(cnt-,cnt,y2);r[lcnt]=L(cnt-,cnt,x2);
}
sort(c+,c+lcnt+);sort(r+,r+lcnt+);
for(int i=cnt;i;--i)
{
int j,id;P now;
j=lower_bound(c+,c+lcnt+,L(,,p[i].y))-c-;
for(;j&&!(p[c[j].l].x<=p[i].x&&p[c[j].r].x>=p[i].x);--j);
if(j)
{
now=P(p[i].x,c[j].x);
if(now==p[c[j].l]) id=c[j].l;
else if(now==p[c[j].r]) id=c[j].r;
else p[id=++cnt]=now;
ins(i,id,dis(now,p[i]));
ins(id,i,dis(now,p[i]));
c[j].s.push_back(id);
}
j=upper_bound(c+,c+lcnt+,L(,,p[i].y))-c;
for(;j<=lcnt&&!(p[c[j].l].x<=p[i].x&&p[c[j].r].x>=p[i].x);++j);
if(j<=lcnt)
{
now=P(p[i].x,c[j].x);
if(now==p[c[j].l]) id=c[j].l;
else if(now==p[c[j].r]) id=c[j].r;
else p[id=++cnt]=now;
ins(i,id,dis(now,p[i]));
ins(id,i,dis(now,p[i]));
c[j].s.push_back(id);
}
j=lower_bound(r+,r+lcnt+,L(,,p[i].x))-r-;
for(;j&&!(p[r[j].l].y<=p[i].y&&p[r[j].r].y>=p[i].y);--j);
if(j<=lcnt)
{
now=P(r[j].x,p[i].y);
if(now==p[r[j].l]) id=r[j].l;
else if(now==p[r[j].r]) id=r[j].r;
else p[id=++cnt]=now;
ins(i,id,dis(now,p[i]));
ins(id,i,dis(now,p[i]));
r[j].s.push_back(id);
}
j=upper_bound(r+,r+lcnt+,L(,,p[i].x))-r;
for(;j<=lcnt&&!(p[r[j].l].y<=p[i].y&&p[r[j].r].y>=p[i].y);++j);
if(j<=lcnt)
{
now=P(r[j].x,p[i].y);
if(now==p[r[j].l]) id=r[j].l;
else if(now==p[r[j].r]) id=r[j].r;
else p[id=++cnt]=now;
ins(i,id,dis(now,p[i]));
ins(id,i,dis(now,p[i]));
r[j].s.push_back(id);
}
}
for(int i=;i<=lcnt;i++)
{
sort(c[i].s.begin(),c[i].s.end(),cmp);
for(int j=;j<c[i].s.size();j++)
{
ins(c[i].s[j],c[i].s[j-],dis(p[c[i].s[j]],p[c[i].s[j-]]));
ins(c[i].s[j-],c[i].s[j],dis(p[c[i].s[j]],p[c[i].s[j-]]));
}
sort(r[i].s.begin(),r[i].s.end(),cmp);
for(int j=;j<r[i].s.size();j++)
{
ins(r[i].s[j],r[i].s[j-],dis(p[r[i].s[j]],p[r[i].s[j-]]));
ins(r[i].s[j-],r[i].s[j],dis(p[r[i].s[j]],p[r[i].s[j-]]));
}
}
dij();
if(d[]<INF) printf("%lld\n",d[]);
else puts("No Path");
}
return ;
}
C题不知道什么鬼,solve=0,貌似数据都是错的,不玩了
[APIO2011]的更多相关文章
- [BZOJ2303][Apio2011]方格染色
[BZOJ2303][Apio2011]方格染色 试题描述 Sam和他的妹妹Sara有一个包含n × m个方格的 表格.她们想要将其的每个方格都染成红色或蓝色. 出于个人喜好,他们想要表格中每个2 × ...
- BZOJ_2303_[Apio2011]方格染色 _并查集
BZOJ_2303_[Apio2011]方格染色 _并查集 Description Sam和他的妹妹Sara有一个包含n × m个方格的 表格.她们想要将其的每个方格都染成红色或蓝色. 出于个人喜好, ...
- 斜率优化入门学习+总结 Apio2011特别行动队&Apio2014序列分割&HZOI2008玩具装箱&ZJOI2007仓库建设&小P的牧场&防御准备&Sdoi2016征途
斜率优化: 额...这是篇7个题的题解... 首先说说斜率优化是个啥,额... f[i]=min(f[j]+xxxx(i,j)) ; 1<=j<i (O(n^2)暴力)这样一个式子,首 ...
- bzoj 2304 [Apio2011]寻路 Dij+模拟+恶心建图
[Apio2011]寻路 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 624 Solved: 193[Submit][Status][Discus ...
- BZOJ 2303: [Apio2011]方格染色 题解
题目大意: 有n*m的方格,中间的数要么是1,要么是0,要求任意2*2的方格中的数异或和为1.已知一部分格子中的数,求合法的填数的方案数. 思路: 由题意得:a[i][j]^a[i][j+1]^a[i ...
- bzoj 2303: [Apio2011]方格染色
传送门 Description Sam和他的妹妹Sara有一个包含n × m个方格的表格.她们想要将其的每个方格都染成红色或蓝色.出于个人喜好,他们想要表格中每个2 × 2的方形区域都包含奇数个(1 ...
- BZOJ 2303: [Apio2011]方格染色 [并查集 数学!]
题意: $n*m:n,m \le 10^6$的网格,每个$2 \times 2$的方格必须有1个或3个涂成红色,其余涂成蓝色 有一些方格已经有颜色 求方案数 太神了!!!花我三节课 首先想了一下只有两 ...
- 【bzoj 2303】【Apio2011】方格染色
题目: http://www.lydsy.com/JudgeOnline/problem.php?id=2303 题解: 很神奇的思路,膜一发大佬http://www.cnblogs.com/HHsh ...
- [APIO2011]方格染色
题解: 挺不错的一道题目 首先4个里面只有1个1或者3个1 那么有一个特性就是4个数xor为1 为什么要用xor呢? 在于xor能把相同的数消去 然后用一般的套路 看看确定哪些值能确定全部 yy一下就 ...
随机推荐
- [Cerc2013]Magical GCD
https://vjudge.net/problem/UVA-1642 题意:在一个序列中,找出一段连续的序列,使得长度*gcd最大 固定右端点,当左端点从左向右移动时,gcd不变或变大 gcd相同时 ...
- python使用tesseract-ocr完成验证码识别(模型训练和使用部分)
一.Tesseract训练 大体流程为:安装jTessBoxEditor -> 获取样本文件 -> Merge样本文件 –> 生成BOX文件 -> 定义字符配置文件 -> ...
- Comet之SSE(Server - Sent - Envent,服务器发送事件)
1.SSE API 先要创建一个新的EventSource对象,并传进一个入口点: var source = new EventSource("myenvent.php"); △: ...
- JAVA_SE基础——56.包的创建
接下来我来给大家讲下--包 , 先看一段代码 class Demo1{ public static void main(String[] args) { System.out.println(&quo ...
- Python 简单聊天室
#coding=utf-8 from socket import * from threading import Thread import time udpSocket = socket(AF_IN ...
- Spring邮件发送1
注意:邮件发送code中,邮件服务器的申请和配置是比较主要的一个环节,博主这里用的是QQ的邮件服务器.有需要的可以谷歌.百度查下如何开通. 今天看了下Spring的官方文档的邮件发送这一章节.在这里记 ...
- jiVMware的网络配置Linux
需求需要配置VMware的虚拟Linux的ip以达到本地可以访问,而且虚拟机Linux可以上网: 第一方案:选择桥接模式 思路:因为桥接可以,使得虚拟机Linux把本地当做一座桥一样连接到路由器,然后 ...
- 剑指offer-两个链表的第一个公共节点
题目描述 输入两个链表,找出它们的第一个公共结点. 解题思路 分析可得如果两个链表有公共节点,那么公共节点出现在两个链表的尾部,即从某一节点开始,两链表之后的节点全部相等.可以首先遍历两个链表得出各自 ...
- Python-Cpython解释器支持的进程与线程-Day9
Cpython解释器支持的进程与线程 阅读目录 一 python并发编程之多进程 1.1 multiprocessing模块介绍 1.2 Process类的介绍 1.3 Process类的使用 1.4 ...
- HTTP协议扫盲(八 )响应报文之 Transfer-Encoding=chunked方式
一.什么是chunked编码? 分块传输编码(Chunked transfer encoding)是只在HTTP协议1.1版本(HTTP/1.1)中提供的一种数据传送机制.以往HTTP的应答中数据是整 ...