版权声明:欢迎转载(请附带原链接)ヾ(๑╹◡╹)ノ https://blog.csdn.net/corsica6/article/details/88841600
*C.Interval Game
跳的贪心方式是唯一的,考虑操作的贪心:
一左一右交替跳一定比同侧优——左跳时贪心选右端点最小的,右跳时贪心选左端点最大的。
枚举第一步是左/右跳分别 模拟出答案后取 即可。
*D.Choosing Points
数据范围的明示:
对于每种
,不能同时选的点之间连边,必然构成一张二分图。
两种
,选
部分的点必然有解,双重染色后找最大的一部分即可。
*E. Walking on a Tree
设每条边被经过次数是 ,答案上界=
大胆猜想一定能达到上界,一个经典的构造证明:
每次删去一个叶子结点
,若
的父边
,则不需要定向处理;否则取出其中两条路径
,为使答案达到上界强制这条条路径反向,假设两条路径的交为
,则这一段都达到了上界,剩下需要决策的实际上为
这条路径。不断删点,就构造出了一组可行解。
*F.Addition and Andition
暴力模拟可证复杂度线性 系列
从高位到低位每位重复模拟
遍处理:
进位时遇到两个数同一位不相同的情况(
)直接暴力进位,否则遇到连续的一段
可以直接移过去,因为从低位的影响不会超过高位,所以不会遇到
。
栈维护下标从大到小(当前位置)的
,复杂度均摊是线性的(不会证,可以感性理解为每弹两次栈最多只会压入一个数对)
code from sigongzi
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define space putchar(' ')
#define enter putchar('\n')
#define MAXN 2000005
#define mp make_pair
#define pb push_back
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
}
struct node {
int id,par;
}sta[MAXN],tmp[MAXN];
int N,M,K,top,cnt,ns[MAXN],nt[MAXN],as[MAXN],at[MAXN];
char s[MAXN],t[MAXN];
void Solve() {
read(N);read(M);read(K);
scanf("%s",s + 1);scanf("%s",t + 1);
reverse(s + 1,s + N + 1);reverse(t + 1,t + M + 1);
for(int i = 1 ; i <= N ; ++i) ns[i] = s[i] - '0';
for(int i = 1 ; i <= M ; ++i) nt[i] = t[i] - '0';
int T = max(N,M);
for(int i = T ; i >= 1 ; --i) {
if(ns[i] == 1 && nt[i] == 1) {
int op = K,pos = i,x = 3;cnt = 0;
while(top) {
if(x == 3) {
if(op >= sta[top].id - pos) {
op -= sta[top].id - pos;
pos = sta[top].id;
tmp[++cnt] = (node){pos,x ^ sta[top].par};
x = x & sta[top].par;
}
else break;
}
else if(x != 0){
if(sta[top].id == pos + 1) {
pos = sta[top].id;
if(x ^ sta[top].par) x = 3;
else x = x & sta[top].par;
}
else break;
}
else break;
--top;
}
if(x != 0 && x != 3) {
++pos;
tmp[++cnt] = (node){pos,x};
}
else if(x) {
pos += op;
as[pos] = at[pos] = 1;
}
for(int j = cnt ; j >= 1 ; --j) sta[++top] = tmp[j];
}
else {
if(ns[i] || nt[i]) {
sta[++top] = (node){i,ns[i] << 1 | nt[i]};
}
}
}
for(int i = 1 ; i <= top ; ++i) {
as[sta[i].id] = (sta[i].par >> 1) & 1;
at[sta[i].id] = sta[i].par & 1;
}
int c = T + K;
while(as[c] == 0) --c;
for(int i = c ; i >= 1 ; --i) {out(as[i]);}
enter;
c = T + K;
while(at[c] == 0) --c;
for(int i = c ; i >= 1 ; --i) {out(at[i]);}
enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}