C - Triple Flips

思路:

小范围暴力

大范围递归构造

构造方法:

solve(l, r) 表示使l 到 r 区间全变为0的方法

为了使反转次数小于等于n/3 + 12

我们只需要保证每次反转后区间长度减少值的期望为3就可以了

如果a[l] == 0, l++

如果a[r] == 0, r--

如果a[l] == 1 && a[l+1] == 1 && a[l+2] == 1, 反转这三个就可以啦, l += 3

如果a[l] == 1 && a[l+1] == 0 && a[l+2] == 1, 反转l, l+2, l+4这三个, l += 3

如果a[l] == 1 && a[l+1] == 0 && a[l+1] == 0, 反转l, l+3, l+6这三个, l += 3

从右区间减少同理

否则只剩下这种情况了:

1 1 0 ...... 0 1 1

那么只需要根据区间长度的奇偶性

反转l , (l+r)/2, r 和 l+1 , (l+1+r-1)/2, r-1 或者 l, (l+r-1)/2, r-1 和 l+1 , (l+1+r)/2, r

然后 l += 3, r -= 3, 区间长度减少6

区间长度小于8的话就暴力

用二进制枚举所有的反转情况, 然后检查

代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head #define ck(l, x, y, z) a[l]==x&&a[l+1]==y&&a[l+2]==z
#define ckk(r, x, y, z) a[r]==x&&a[r-1]==y&&a[r-2]==z
const int N = 1e5 + ;
int a[N], tmp[N], n;
vector<piii> ans;
bool f = false;
void flip(int x, int y, int z) {
a[x] ^= ;
a[y] ^= ;
a[z] ^= ;
ans.pb({{x, y}, z});
}
void fflip(int x, int y) {
a[x] ^= ;
a[x+y>>] ^= ;
a[y] ^= ;
ans.pb({{x, x+y>>}, y});
}
void Flip(int x, int y) {
tmp[x] ^= ;
tmp[x+y>>] ^= ;
tmp[y] ^= ;
//ans.pb({{x, x+y>>1}, y});
}
void bruteforce(int l, int r) {
vector<pii> vc;
for (int i = l; i <= r; i++) {
for (int j = i+; j <= r; j += ) {
vc.pb({i, j});
}
}
int sz = vc.size();
for (int i = ; i < (<<sz); i++) {
for (int j = l; j <= r; j++) tmp[j] = a[j];
for (int j = ; j < sz; j++) {
if(i&(<<j)) {
Flip(vc[j].fi, vc[j].se);
}
}
bool ff = true;
for (int j = l; j <= r; j++) if(tmp[j]) {ff = false; break;}
if(ff) {
f = true;
for (int j = ; j < sz; j++) if(i&(<<j))ans.pb({{vc[j].fi, vc[j].fi + vc[j].se >> }, vc[j].se});
return ;
}
}
}
void solve(int l, int r) {
if(r - l + <= ) {
while(r-l+ < && l > ) l--;
while(r-l+ < && r < n) r++;
bruteforce(l, r);
return ;
}
if(a[l] == ) {
solve(l+, r);
return ;
}
if(a[r] == ) {
solve(l, r-);
return ;
}
if(ck(l, , , )) {
flip(l, l+, l+);
solve(l+, r);
return ;
}
if(ck(l, , , )) {
flip(l, l+, l+);
solve(l+, r);
return ;
}
if(ck(l, , , )) {
flip(l, l+, l+);
solve(l+, r);
return ;
}
if(ckk(r, , , )) {
flip(r, r-, r-);
solve(l, r-);
return ;
}
if(ckk(r, , , )) {
flip(r, r-, r-);
solve(l, r-);
return ;
}
if(ckk(r, , , )) {
flip(r, r-, r-);
solve(l, r-);
return ;
}
if((r-l+)&) {
fflip(l, r);
fflip(l+, r-);
solve(l+, r-);
return ;
}
else {
fflip(l, r-);
fflip(l+, r);
solve(l+, r-);
return ;
}
}
int main() {
int cnt = ;
scanf("%d", &n);
for (int i = ; i <= n; i++) scanf("%d", &a[i]);
solve(, n);
if(f) {
printf("YES\n");
printf("%d\n", (int)ans.size());
for (piii p : ans) printf("%d %d %d\n", p.fi.fi, p.fi.se, p.se);
}
else printf("NO\n");
return ;
}

Codeforces 1071 C - Triple Flips的更多相关文章

  1. Codeforces 1071C Triple Flips 构造

    原文链接 https://www.cnblogs.com/zhouzhendong/p/CF1071C.html 题目传送门 - CF1071C 题意 给定一个长度为 n 的 01 数列,限定你在 $ ...

  2. Codeforces1071C Triple Flips 【构造】【Four Russians】

    题目分析: 这种题目显然可以先考虑哪些无解.我们发现我们不考虑操作次数的时候,我们可以选择连续的三个进行异或操作. 这样我们总能使得一个序列转化为$000...000xy$的形式.换句话说,对于$00 ...

  3. [CF1031E]Triple Flips

    题目大意:给你一个长度为$n$的$01$串,一次操作定义为:选取$3$个等距的元素,使其$0$变$1$,$1$变$0$,要求在$\Big\lfloor \dfrac n 3\Big\rfloor+12 ...

  4. Codeforces Round #517

    传送门 A. Cram Time 你有一本书,阅读第\(i\)页需要花费\(i\)的时间.你第一天有\(a\)的时间,第二天有\(b\)的时间,问你的总阅读页数的最大值. Input: 一行包含\(2 ...

  5. Technocup 2019 - Elimination Round 2

    http://codeforces.com/contest/1031 (如果感觉一道题对于自己是有难度的,不要后退,懂0%的时候敲一遍,边敲边想,懂30%的时候敲一遍,边敲边想,懂60%的时候敲一遍, ...

  6. Codeforces 1119H - Triple(FWT)

    Codeforces 题目传送门 & 洛谷题目传送门 FWT 的 immortal tea %%% 首先我们可以写出一个朴素的 \(dp\),设 \(dp_{i,j}\) 表示考虑前 \(i\ ...

  7. Good Triple CodeForces - 1169D (等差子序列)

    大意: 给定01字符串, 求有多少个区间$[l,r]$, 使得存在正整数$x,k$满足$1\le x,k\le n,l\le x<x+2k\le r,s_x=s_{x+k}=s_{x+2k}$. ...

  8. CodeForces 304C

    E - E Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Statu ...

  9. Codeforces Round #368 (Div. 2) C. Pythagorean Triples(数学)

    Pythagorean Triples 题目链接: http://codeforces.com/contest/707/problem/C Description Katya studies in a ...

随机推荐

  1. 【题解】Luogu SP8791 DYNALCA - Dynamic LCA

    原题传送门 这题用Link-Cut-Tree解决,Link-Cut-Tree详解 这道题的难点就在如何求LCA: 我们珂以先对其中一个点进行access操作,然后对另一个点进行access操作,因为L ...

  2. Redis热点Key发现及常见解决方案!

    一.热点Key问题产生的原因 1.用户消费的数据远大于生产的数据(热卖商品.热点新闻.热点评论.明星直播). 在日常工作生活中一些突发的的事件,例如:双十一期间某些热门商品的降价促销,当这其中的某一件 ...

  3. SCOI 2018 划水记

    (此处不应有目录,省选爆零的过程得慢慢看) Day -n 一诊 说真的,在没看到“第一次诊断性考试”之前,一直以为是“一整”,真是可怕,初中教育都开始像UW中的最高祭司学习了. 感觉题目很gg.于是考 ...

  4. Win7 配置免安装mysql5.7.20过程详解

    转载:https://www.2cto.com/database/201406/312689.html 转载:http://blog.csdn.net/hekaihaw/article/details ...

  5. Restful framework【第六篇】认证组件

    基本用法 -认证功能 1 写一个类,继承BaseAuthentication 2 def authenticate(self,request) ,记住传request对象 -如果验证通过,返回None ...

  6. 再谈fedora 23中的flash的安装

    安装下载, flash插件的地址是 https://get.adobe.com/flashplayer/ ls 的显示, 记住两个很常用的选项: 指定 "假设的屏幕的宽度" , - ...

  7. Python中的open和codecs.open

    最近老被编码困扰,多次折腾之后,感觉python的编解码做得挺好的,只要了解下边的流程,一般都能解决 input文件(gbk, utf-8...) ----decode-----> unicod ...

  8. oracle 之 统计函数、子查询、操作符

    统计函数 COUNT():查询表中的数据记录 AVG():求出平均值 SUM():求和 MAX():求出最大值 MIN():Q求出最小值 子查询   [单行多列] select * from a wh ...

  9. Awesome Torch

    Awesome Torch This blog from: A curated list of awesome Torch tutorials, projects and communities. T ...

  10. Gtk 窗口,控件,设置(添加图片等)

    1.关于窗口   // 创建顶层窗体,后面有POPUP的 GtkWidget *main_window; main_window = gtk_window_new (GTK_WINDOW_TOPLEV ...