chessboard
题意: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的更多相关文章
- LightOJ1171 Knights in Chessboard (II)(二分图最大点独立集)
题目 Source http://www.lightoj.com/volume_showproblem.php?problem=1171 Description Given an m x n ches ...
- CodeForces445A DZY Loves Chessboard
A. DZY Loves Chessboard time limit per test 1 second memory limit per test 256 megabytes input stand ...
- FJOI省队集训 chessboard
(题目懒得打字了,建议到新窗口查看) 显然这玩意儿是可以按位搞的...然后就是一个裸的最小割模型? 然而这样做理论上只有30分实际上有40分. 事实上我们可以发现,每一列的取值只和上一列有关,这样我们 ...
- [poj2446]Chessboard
Description 给定一个m×n的棋盘,上面有k个洞,求是否能在不重复覆盖且不覆盖到洞的情况下,用2×1的卡片完全覆盖棋盘. Input 第一行有三个整数n,m,k(0<m,n<=3 ...
- UESTC 1851 Kings on a Chessboard
状压DP... Kings on a Chessboard Time Limit: 10000ms Memory Limit: 65535KB This problem will be judged ...
- UVa12633 Super Rooks on Chessboard(容斥 + FFT)
题目 Source http://acm.hust.edu.cn/vjudge/problem/42145 Description Let’s assume there is a new chess ...
- poj 2446 Chessboard (二分匹配)
Chessboard Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 12800 Accepted: 4000 Descr ...
- 周赛-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 ...
- DZY Loves Chessboard
DescriptionDZY loves chessboard, and he enjoys playing with it. He has a chessboard of n rows and m ...
- UVa 10161 Ant on a Chessboard
一道数学水题,找找规律. 首先要判断给的数在第几层,比如说在第n层.然后判断(n * n - n + 1)(其坐标也就是(n,n)) 之间的关系. 还要注意n的奇偶. Problem A.Ant o ...
随机推荐
- 20155334 网络对抗PC平台逆向破解(二)
注入Shellcode并运行攻击 shellcode就是一段机器指令(code) 通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe) ...
- MVVM Light Toolkit使用指南
原文:MVVM Light Toolkit使用指南 原文地址: https://blog.csdn.net/ldld1717/article/details/77040077 概述 MVVM Lig ...
- mfc 线程的诞生和死亡
知识点: 线程概念 线程的诞生 线程的死亡 一. 线程: 线程,是程序执行流的最小单元. 另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点 ...
- Linux 入门记录:十二、Linux 权限机制
一.权限 权限是操作系统用来限制资源访问的机制,权限一般分为读.写.执行. 系统中每个文件都拥有特定的权限.所属用户及所属组,通过这样的机制来限制哪些用户.哪些组可以对特定的文件进行什么样的操作. 每 ...
- 阿里云centos 安装禅道
下载 我的阿里云服务器系统是 centos6.8 64 位,下载的禅道版本是 Linux 64位一键安装包(适用于Linux 64位) 由于阿里云服务器没桌面,所以下载用不了浏览器,可考虑在本地下载后 ...
- BugkuCTF web2
前言 写了这么久的web题,算是把它基础部分都刷完了一遍,以下的几天将持续更新BugkuCTF WEB部分的题解,为了不影响阅读,所以每道题的题解都以单独一篇文章的形式发表,感谢大家一直以来的支持和理 ...
- 将Centos 的默认yum源改为阿里云的yum源后出现的问题
阿里各版本yum源如下: Centos5:http://mirrors.aliyun.com/repo/Centos-5.repo Centos6:http://mirrors.aliyun.com/ ...
- GitHub 新手教程 七,Git GUI 新手教程(4),上传本地代码库到GitHub
1,打开 GitGUI,单击我们之前克隆好的本地库: 2,按图示顺序点击按钮: 3,按图示顺序点击按钮,输入您的 Sign 信息: 4,按图示顺序点击按钮: 5,弹出新的窗口后,点击 “Push” 按 ...
- 安装Ubuntu后要做的事
优化 删除libreoffice sudo apt-get remove libreoffice-common 删除Amazon sudo apt-get remove unity-webapps-c ...
- 212. Space Replacement【LintCode by java】
Description Write a method to replace all spaces in a string with %20. The string is given in a char ...