【GDKOI 2024 TG Day2】染色(set) 题解
发现我们给一个点染上色后有:

我们称这是一个大小为 1 的十字。
进一步地,我们给这 5 个点再次染上色后有:

我们称这是一个大小为 2 的十字。
同理可得,我们给这 5 个点染上相同的大小为 2 的十字,可得一个大小为 4 的十字:

假设我们图的边长为 \(N=2^n\),我们只需要染上一个大小为 \(w=\frac{N}{2}\) 的十字,左边的那一个点就会和右边的点抵消,上面的点就会和下面的点抵消。最终效果就是只染了一个点。

假如我们要染一个大小为 \(w=\frac{N}{2}\) 的十字,可以通过在这个十字的 5 个红色的点位染上 5 个大小为 \(\frac{w}{2}=\frac{N}{4}\) 的十字来实现:

同理,我们可以使用分治来实现这一过程,最后就只会需要染若干个大小为 1 的十字,这就是题目“绘画操作”的定义。
我们只需要对于每个需要染色的位置跑一遍分治即可。时间复杂度由 \(T(n)=5T(\frac{n}{2})+O(1)\) 得 \(O(N^2n^{\log_25})\),期望得分 35。
#include <cstdio>
#include <cstdlib>
#include <set>
#define ll long long
#define N 3000
using namespace std;
ll n, siz;
ll a[N][N], v[N][N];
ll tot;
inline ll calc(ll x) {
return (x%siz+siz)%siz;
}
void fun(ll x, ll y, ll w) {
if(w == 1) {
v[x][y] ^= 1;
return;
}
fun(x, y, w/2);
fun(calc(x+w/2), y, w/2);
fun(calc(x-w/2), y, w/2);
fun(x, calc(y+w/2), w/2);
fun(x, calc(y-w/2), w/2);
}
int main() {
freopen("set.in", "r", stdin);
freopen("set.out", "w", stdout);
scanf("%lld", &n);
siz = 1<<n;
for(ll i = 0; i < siz; i++) {
for(ll j = 0; j < siz; j++) {
scanf("%lld", &a[i][j]);
}
}
for(ll i = 0; i < siz; i++) {
for(ll j = 0; j < siz; j++) {
if(a[i][j]) {
fun(i, j, siz / 2);
}
}
}
for(ll i = 0; i < siz; i++) {
for(ll j = 0; j < siz; j++) {
if(v[i][j]) {
tot++;
}
}
}
printf("%lld\n", tot);
for(ll i = 0; i < siz; i++) {
for(ll j = 0; j < siz; j++) {
if(v[i][j]) {
printf("%lld %lld\n", i, j);
}
}
}
}
考虑为什么会这么慢,因为一个点可能被染了多次,这可以被抵消,我们可以枚举 \(w\),然后再同理得解。时间复杂度 \(O(N^2n)\),期望 100。
不要开 long long。
#include <cstdio>
#include <cstdlib>
#include <set>
#define N 3000
using namespace std;
int n, siz;
bool a[N][N], v[N][N];
int tot;
inline int calc(int x) {
return (x % siz + siz) % siz;
}
inline int read() {
int x = 0;
char c = '.';
while(c < '0' || c > '9') c = getchar();
while(c >= '0' && c <= '9') {
x = (x << 1) + (x << 3) + (c ^ '0');
c = getchar();
}
return x;
}
void print(int x) {
if(x > 9) print(x / 10);
putchar(x % 10 + '0');
}
int main() {
freopen("set.in", "r", stdin);
freopen("set.out", "w", stdout);
n = read();
siz = 1<<n;
for(int i = 0; i < siz; i++) {
for(int j = 0; j < siz; j++) {
a[i][j] = read();
}
}
for(int w = siz/2; w >= 2; w /= 2) {
for(int i = 0; i < siz; i++) {
for(int j = 0; j < siz; j++) {
v[i][j] = 0;
}
}
for(int i = 0; i < siz; i++) {
for(int j = 0; j < siz; j++) {
if(a[i][j]) {
v[i][j] ^= 1;
v[calc(i+w/2)][j] ^= 1;
v[calc(i-w/2)][j] ^= 1;
v[i][calc(j+w/2)] ^= 1;
v[i][calc(j-w/2)] ^= 1;
}
}
}
for(int i = 0; i < siz; i++) {
for(int j = 0; j < siz; j++) {
a[i][j] = v[i][j];
}
}
}
for(int i = 0; i < siz; i++) {
for(int j = 0; j < siz; j++) {
if(v[i][j]) {
tot++;
}
}
}
print(tot);
putchar('\n');
for(int i = 0; i < siz; i++) {
for(int j = 0; j < siz; j++) {
if(v[i][j]) {
print(i);
putchar(' ');
print(j);
putchar('\n');
}
}
}
}
【GDKOI 2024 TG Day2】染色(set) 题解的更多相关文章
- noip2014提高组day2二题题解-rLq
(又是昨天的作业……本题写于昨天) (这破题都做这么久,我是不是吃枣药丸……) (好吧这是一道图论题呢) 本题地址:http://www.luogu.org/problem/show?pid=2296 ...
- 【转】TYVJ 1695 计算系数(NOIP2011 TG DAY2 1)
计算系数 题目描述 给定一个多项式(ax + by)k,请求出多项式展开后xn ym项的系数. [数据范围] 对于 30%的数据,有0≤k≤10: 对于 50%的数据,有a = 1,b = 1: 对于 ...
- 【NOIP2013】Day2不完全题解+代码
T1 直接递归区间,从1-n开始,找到这个区间中的最小值然后将区间里的所有值都减去这个最小值 以被减去最小值之后的零点为分段分别递归处理即可. #include <algorithm> # ...
- CH Round #58 - OrzCC杯noip模拟赛day2
A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...
- CH Round #49 - Streaming #4 (NOIP模拟赛Day2)
A.二叉树的的根 题目:http://www.contesthunter.org/contest/CH%20Round%20%2349%20-%20Streaming%20%234%20(NOIP 模 ...
- BJOI2018爆零记
没啥可说的 Day1 0分 T1 给你一个二进制串,每次修改一个位置,询问[l,r]区间中有多少二进制子串重排后能被3整除 T2 一个无向图(无重边自环)每个点有一个包含两种颜色的染色集合,一个边的两 ...
- Vijos P1740聪明的质检员
题目 描述 小 T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有n个矿石,从1到n逐一编号,每个矿石都有自己的重量wi以及价值vi.检验矿产的流程是:1.给定m个区间[Li,Ri]:2. ...
- AtCoder Grand Contest 015
传送门 A - A+...+B Problem 题意:n个数最大值a,最小值b,求和的可能数量. #include<cstdio> #include<algorithm> us ...
- dp水一天
水一些dp的联系题 标签: dp ###hdu_2045 题意 一穿珠子,用三种颜色染色,要求相邻的珠子和两端的珠子不能是同一种颜色,求当有n个珠子的时候有几种染色方案 题解 表示dp[i][j][k ...
- 【CF1141G】Privatization of Roads in Treeland
题目大意:给定一个 N 个点的无根树,现给这个树进行染色.定义一个节点是坏点,若满足与该节点相连的至少两条边是相同的颜色,求至多有 k 个坏点的情况下最少需要几种颜色才能进行合法染色. 题解:考虑一个 ...
随机推荐
- Java中关键字-instanceof-的真实应用场景-2022新项目
instanceof关键字主要用来判断两个对象是否为同一种类型,举个例子如果有猫类.动物类,猫类继承自动物类: 判断某个类是否为动物类,就可以使用instanceof关键字.下面简单介绍几种真实的应用 ...
- snippet n. 小片, 片断, 摘录 单词记忆
snippet 助记:snip[剪断] + -et小词后缀. 关键是 snip 怎么记忆 snip : 拟声词,模仿剪断东西的声音. 助记单词 slip 滑 根据字母 n是done的缩写,可以 想成 ...
- 基于泰凌微TLSR8355的无线灯光智能控制系统解决方案调试总结
前记 随着新技术的不断发展,在灯控市场.使用无线和传感器技术让灯的利用变得更加环保和智能是一个相对时尚的选择.最近跟几个客户做了一些此类的产品.发掘了一些有趣的功能和应用.这里做一个梳理. 特色梳理 ...
- day14--Java常用类之字符串相关类02
Java常用类 2.字符串相关类 String.StringBuilder.StringBuffer类是三个字符串相关类. String类代表不可变字符序列,StringBuilder类和String ...
- Android中同步类Mutex(AutoMutex)与Condition
在Android中,封装的同步类主要有Mutex(AutoMutex)与Condition. 这两个类在android中被大量的使用,这也说明这两个类是非常重要的. 一.Mutex(AutoMutex ...
- 使用zxing来生成二维码
使用zxing来生成二维码 二维码已经成为了现代生活中不可或缺的一部分,无论是商业还是个人使用,二维码都有着广泛的应用.而在二维码的生成过程中,zxing是一款非常优秀的开源库,它提供了一系列的API ...
- [vscode]使用cmake时将命令行参数传递给调试目标
一.简介 本文介绍了在vscode中使用cmake工具时,如何传递参数给编译目标的方法. 前提:使用vscode+cmake编译C/C++程序. 二.方法 在.vscode/目录下新建settings ...
- 记录-关于console你不知道的那些事
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 了解 console ● 什么是 console ? console 其实是 JavaScript 内的一个原生对象 内部存储的方法大部分 ...
- C# 优雅的处理TCP数据(心跳,超时,粘包断包,SSL加密 ,数据处理等)
Tcp是一个面向连接的流数据传输协议,用人话说就是传输是一个已经建立好连接的管道,数据都在管道里像流水一样流淌到对端.那么数据必然存在几个问题,比如数据如何持续的读取,数据包的边界等. Nagle's ...
- .NET分布式Orleans - 4 - 计时器和提醒
Timer是什么 Timer 是一种用于创建定期粒度行为的机制. 与标准的 .NET System.Threading.Timer 类相似,Orleans 的 Timer 允许在一段时间后执行特定的操 ...