题意:n*n的矩阵,m次赋值一个子矩阵为c,最后输出答案。

n<=1e3 m<=1e5

解:倒序处理。

拆行处理。

每行内并查集维护未被赋值的地方。

这样每个地方最多被赋值一次,每次修改要访问n行,时间复杂度是O(n(n + m))

 #include <cstdio>

 inline void read(int &x) {
char c = getchar();
x = ;
while(c < '' || c > '') {
c = getchar();
}
while(c >= '' && c <= '') {
x = (x << ) + (x << ) + c - ;
c = getchar();
}
return;
} const int N = , M = ; struct Node {
int opt, c, x, y, xx, yy;
}a[M]; int n, k, m, fa[M], sv[M], num, path[M], top;
char s[]; struct ROW {
int a[N], fa[N];
ROW() {
for(int i = ; i < N; i++) {
fa[i] = i;
a[i] = ;
}
}
int find(int x) {
if(x == fa[x]) {
return x;
}
return fa[x] = find(fa[x]);
}
inline void change(int v, int l, int r) {
int p = find(r);
while(p >= l) {
a[p] = v;
fa[p] = find(p - );
p = fa[p];
}
return;
}
}row1[N], row2[N]; int main() { read(n);
read(k);
read(m); for(int i = ; i <= m; i++) {
scanf("%s", s);
if(s[] == 'P') { // print
fa[i] = i - ;
a[i].opt = ;
read(a[i].c);
read(a[i].x);
read(a[i].y);
read(a[i].xx);
read(a[i].yy);
}
else if(s[] == 'S') { // save
fa[i] = i - ;
sv[++num] = i;
}
else { // load
int x;
//scanf("%d", &x);
read(x);
fa[i] = sv[x];
}
} int x = m;
while(x) {
path[++top] = x;
x = fa[x];
} for(int e = ; e <= top; e++) {
int i = path[e];
if(!a[i].opt) {
continue;
} for(int j = a[i].x + ; j <= a[i].xx + ; j++) {
//printf(" j = %d c = %d \n", j, a[i].c);
if((a[i].x - + a[i].y) & ) {
row1[j].change(a[i].c, a[i].y + , a[i].yy + );
}
else {
row2[j].change(a[i].c, a[i].y + , a[i].yy + );
}
}
} for(int i = ; i <= n; i++) {
for(int j = ; j <= n; j++) {
if((i + j) & ) {
printf("%d ", row2[i].a[j]);
}
else {
printf("%d ", row1[i].a[j]);
}
}
puts("");
}
return ;
}

AC代码

说一下原来的题意:

有个矩阵,每次间隔染色一个子矩阵(类似国际象棋那样,左上角要染),还要支持存档/读档。最后一次输出。

 #include <cstdio>
#include <algorithm> inline void read(int &x) {
char c = getchar();
x = ;
while(c < '' || c > '') {
c = getchar();
}
while(c >= '' && c <= '') {
x = (x << ) + (x << ) + c - ;
c = getchar();
}
return;
} const int N = , M = ; struct Node {
int opt, c, x, y, xx, yy;
}a[M]; int n, k, m, fa[M], sv[M], num, path[M], top;
char s[];
int sa[N * N * ], sb[N * N * ], sc[N * N * ], sd[N * N * ];
int tag1[N * N * ], tag2[N * N * ], G[N][N]; void build(int x, int y, int xx, int yy, int o) {
if(x == xx && y == yy) {
tag1[o] = ;
return;
}
int mx = (x + xx) >> ;
int my = (y + yy) >> ; sa[o] = ++num;
build(x, y, mx, my, num); if(yy > y) {
sb[o] = ++num;
build(x, my + , mx, yy, num);
}
if(xx > x) {
sc[o] = ++num;
build(mx + , y, xx, my, num);
} if(yy > y && xx > x) {
sd[o] = ++num;
build(mx +, my + , xx, yy, num);
}
return;
} inline void pushdown(int x, int y, int xx, int yy, int o) {
int mx = (x + xx) >> ;
int my = (y + yy) >> ;
if(tag1[o]) {
int t = tag1[o];
if(sa[o]) {
tag1[sa[o]] = t;
}
if(sb[o]) {
if((my - y + ) & ) {
tag2[sb[o]] = t;
}
else {
tag1[sb[o]] = t;
}
}
if(sc[o]) {
if((mx - x + ) & ) {
tag2[sc[o]] = t;
}
else {
tag1[sc[o]] = t;
}
}
if(sd[o]) {
if((mx - x + my - y + ) & ) {
tag1[sd[o]] = t;
}
else {
tag2[sd[o]] = t;
}
}
tag1[o] = ;
}
if(tag2[o]) {
int t = tag2[o];
if(sa[o]) {
tag2[sa[o]] = t;
}
if(sb[o]) {
if((my - y + ) & ) {
tag1[sb[o]] = t;
}
else {
tag2[sb[o]] = t;
}
}
if(sc[o]) {
if((mx - x + ) & ) {
tag1[sc[o]] = t;
}
else {
tag2[sc[o]] = t;
}
}
if(sd[o]) {
if((mx - x + my - y + ) & ) {
tag2[sd[o]] = t;
}
else {
tag1[sd[o]] = t;
}
}
tag2[o] = ;
}
return;
} int X, XX, Y, YY;
inline void change(int v, int f, int x, int y, int xx, int yy, int o) {
int mx = (x + xx) >> ;
int my = (y + yy) >> ;
if(X <= x && xx <= XX) {
if(Y <= y && yy <= YY) {
if(f) {
tag1[o] = v;
}
else {
tag2[o] = v;
}
return;
}
}
pushdown(x, y, xx, yy, o);
if(X <= mx && Y <= my) { // sa
change(v, f, x, y, mx, my, sa[o]);
}
if(X <= mx && my < YY) { // sb
if((my - y + ) & ) {
change(v, f ^ , x, my + , mx, yy, sb[o]);
}
else {
change(v, f, x, my + , mx, yy, sb[o]);
}
}
if(mx < XX && Y <= my) { // sc
if((mx - x + ) & ) {
change(v, f ^ , mx + , y, xx, my, sc[o]);
}
else {
change(v, f, mx + , y, xx, my, sc[o]);
}
}
if(mx < XX && my < YY) { // sd
if((mx - x + my - y + ) & ) {
change(v, f, mx + , my + , xx, yy, sd[o]);
}
else {
change(v, f ^ , mx + , my + , xx, yy, sd[o]);
}
}
return;
} void ed(int x, int y, int xx, int yy, int o) {
if(x == xx && y == yy) {
G[x][y] = tag1[o];
return;
}
int mx = (x + xx) >> ;
int my = (y + yy) >> ;
pushdown(x, y, xx, yy, o);
ed(x, y, mx, my, sa[o]);
if(yy > y) {
ed(x, my + , mx, yy, sb[o]);
}
if(xx > x) {
ed(mx + , y, xx, my, sc[o]);
}
if(xx > x && yy > y) {
ed(mx + , my + , xx, yy, sd[o]);
}
return;
} int main() { read(n);
read(k);
read(m); for(int i = ; i <= m; i++) {
scanf("%s", s);
if(s[] == 'P') { // print
fa[i] = i - ;
a[i].opt = ;
read(a[i].c);
read(a[i].x);
read(a[i].y);
read(a[i].xx);
read(a[i].yy);
}
else if(s[] == 'S') { // save
fa[i] = i - ;
sv[++num] = i;
}
else { // load
int x;
read(x);
fa[i] = sv[x];
}
} int x = m;
while(x) {
path[++top] = x;
x = fa[x];
}
std::reverse(path + , path + top + );
num = ;
build(, , n, n, );
for(int e = ; e <= top; e++) {
int i = path[e];
if(!a[i].opt) {
continue;
}
a[i].x++;
a[i].xx++;
a[i].y++;
a[i].yy++;
X = a[i].x;
Y = a[i].y;
XX = a[i].xx;
YY = a[i].yy;
if((a[i].x - + a[i].y) & ) {
change(a[i].c, , , , n, n, );
}
else {
change(a[i].c, , , , n, n, );
}
} ed(, , n, n, );
for(int i = ; i <= n; i++) {
for(int j = ; j <= n; j++) {
printf("%d ", G[i][j]);
}
puts("");
}
return ;
}

四分树

这是考场上写的,四分树每次修改貌似是O(n)的,但是卡成6s......只有75分。

话说我第一次写四分树居然是在考场上,而且一个字符都没调就一次写对了......

时间复杂度到底是多少呀......nm的话应该能过呀?莫非是我常数大?

chessboard的更多相关文章

  1. LightOJ1171 Knights in Chessboard (II)(二分图最大点独立集)

    题目 Source http://www.lightoj.com/volume_showproblem.php?problem=1171 Description Given an m x n ches ...

  2. CodeForces445A DZY Loves Chessboard

    A. DZY Loves Chessboard time limit per test 1 second memory limit per test 256 megabytes input stand ...

  3. FJOI省队集训 chessboard

    (题目懒得打字了,建议到新窗口查看) 显然这玩意儿是可以按位搞的...然后就是一个裸的最小割模型? 然而这样做理论上只有30分实际上有40分. 事实上我们可以发现,每一列的取值只和上一列有关,这样我们 ...

  4. [poj2446]Chessboard

    Description 给定一个m×n的棋盘,上面有k个洞,求是否能在不重复覆盖且不覆盖到洞的情况下,用2×1的卡片完全覆盖棋盘. Input 第一行有三个整数n,m,k(0<m,n<=3 ...

  5. UESTC 1851 Kings on a Chessboard

    状压DP... Kings on a Chessboard Time Limit: 10000ms Memory Limit: 65535KB This problem will be judged ...

  6. UVa12633 Super Rooks on Chessboard(容斥 + FFT)

    题目 Source http://acm.hust.edu.cn/vjudge/problem/42145 Description Let’s assume there is a new chess ...

  7. poj 2446 Chessboard (二分匹配)

    Chessboard Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 12800   Accepted: 4000 Descr ...

  8. 周赛-DZY Loves Chessboard 分类: 比赛 搜索 2015-08-08 15:48 4人阅读 评论(0) 收藏

    DZY Loves Chessboard time limit per test 1 second memory limit per test 256 megabytes input standard ...

  9. DZY Loves Chessboard

    DescriptionDZY loves chessboard, and he enjoys playing with it. He has a chessboard of n rows and m ...

  10. UVa 10161 Ant on a Chessboard

    一道数学水题,找找规律. 首先要判断给的数在第几层,比如说在第n层.然后判断(n * n - n + 1)(其坐标也就是(n,n)) 之间的关系. 还要注意n的奇偶.  Problem A.Ant o ...

随机推荐

  1. typedef你真的理解么?

    typedef,用最简单的话去诠释他,那么就是给类型取别名!!!  但是他并没有你想象的那么简单! 举例: typedef int size;//那么int就有一个别名叫size了,以后就可以 siz ...

  2. python 穷举法 算24点(史上最简短代码)

    本来想用回溯法实现 算24点.题目都拟好了,就是<python 回溯法 子集树模板 系列 -- 7.24点>.无奈想了一天,没有头绪.只好改用暴力穷举法. 思路说明 根据四个数,三个运算符 ...

  3. [CF1059E]Split the Tree[贪心+树上倍增]

    题意 给定 \(n\) 个节点的树,点有点权 \(w\) ,划分成多条儿子到祖先的链,要求每条链点数不超过 \(L\) ,和不超过 \(S\),求最少划分成几条链. \(n\leq 10^5\) . ...

  4. Grid布局20行代码快速生成瀑布流

    网格布局 Grid 布局,好用又简单,至少比 Flex 要人性化一点,美中不足就是浏览器支持度差点. DOM结构 中间夹层为了后续拓展. CSS .grid { display: grid; grid ...

  5. tree的使用,显示行号,find命令应用

    第1章 linux启动过程 1.开机自检bios 2.mbr引导 3.GRUB 菜单:选择不同的内核 4.加载内核 5.运行init进程 6.读取/etc/inittab运行级别配置文件 7.执行 / ...

  6. 移动webapp的那些令你头疼的事

    bug持续更新中... 测试浏览器 Chrome: 61.0.3163.73 Safari: 10.0(IOS 10.3.3) Github: webapp-bugs 1. IOS overflow: ...

  7. phabricator 结合 arcanist 使用

    简介 arcanist 是 phabricator 接口的命令工具,主要用于提交 diff 和 push review 通过的commit. 安装 下载源码,然后指定系统的环境变量即可 $ some_ ...

  8. Android 测试之Monkey

    一.什么是Monkey Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中.它向系统发送伪随机的用户事件流(如按键输入.触摸屏输入.手势输入等),实现对正在开发的应用程序进 ...

  9. 初学Direct X(7) ——位图的旋转,缩放以及平移

    初学Direct X(7) --位图的旋转,缩放以及平移 本文旨在实现通过D3DXMatrixTransformation2D函数实现位图的旋转,缩放以及平移操作,但是具体的原理部分会在后面进一步的探 ...

  10. 如何理解nexus

    理解: Nexus即区块链:分布式部署肯定是构建去中心化网络理所当然的解决方向--通过P2P协议将全世界所有节点计算机彼此相互连接,形成一张密密麻麻的网络:以巧妙的机制,通过节点之间的交易数据同步来保 ...