[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一下就 ...
随机推荐
- iOS中CocoaPods的安装及错误详解
什么是CocoaPods CocoaPods是OS X和iOS下的一个第三类库管理工具,通过CocoaPods工具我们可以为项目添加被称为"Pods"的依赖库(这些类库必须是Coc ...
- day-4 python多进程编程知识点汇总
1. python多进程简介 由于Python设计的限制(我说的是咱们常用的CPython).最多只能用满1个CPU核心.Python提供了非常好用的多进程包multiprocessing,他提供了一 ...
- nyoj 阶乘0
阶乘的0 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 计算n!的十进制表示最后有多少个0 输入 第一行输入一个整数N表示测试数据的组数(1<=N< ...
- js判断操作系统windows,ios,android(笔记)
使用JS判断用户使用的系统是利用浏览器的userAgent. navigator.userAgent:userAgent 获取了浏览器用于 HTTP 请求的用户代理头的值. navigator.pla ...
- iot会议纪要 20180105
1.需求概述设备 <-->物接入 <--> 云端认证授权协议解析主题 端点endpoint(地址)->设备thing(用户)->身份principal(密码)-&g ...
- 访问远程的docker
docker version vim /etc/default/docker DOCKER_OPTS=" -Label name=dockerserver2" docke ...
- DevExpress控件的GridControl实现行多选
最近用到DevExpress控件的GridControl控件,需要用到行多选的操作,在网上找的资料,自己总结一下. 先展示一下效果:
- python 开发之路 - 入门
一. python 介绍 Python是著名的"龟叔"Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言.1991年 发布Python ...
- WPF绘制光滑连续贝塞尔曲线
1.需求 WPF本身没有直接把点集合绘制成曲线的函数.可以通过贝塞尔曲线函数来绘制. 贝塞尔曲线类是:BezierSegment,三次贝塞尔曲线,通过两个控制点来控制开始和结束方向. Quadrati ...
- scrapy 选择器官方文档
当抓取网页时,常见的任务是从HTML源码中提取数据.现有的一些库可以达到这个目的: BeautifulSoup lxml Scrapy 提取数据有自己的一套机制.它们被称作选择器(seletors), ...