zoukankan      html  css  js  c++  java
  • Codeforces 1382C2

    C2. Prefix Flip (Hard Version)

    time limit per test1 second
    memory limit per test256 megabytes
    input standard input
    output standard output
    This is the hard version of the problem. The difference between the versions is the constraint on n and the required number of operations. You can make hacks only if all versions of the problem are solved.

    There are two binary strings a and b of length n (a binary string is a string consisting of symbols 0 and 1). In an operation, you select a prefix of a, and simultaneously invert the bits in the prefix (0 changes to 1 and 1 changes to 0) and reverse the order of the bits in the prefix.

    For example, if a=001011 and you select the prefix of length 3, it becomes 011011. Then if you select the entire string, it becomes 001001.

    Your task is to transform the string a into b in at most 2n operations. It can be proved that it is always possible.

    Input

    The first line contains a single integer t (1≤t≤1000) — the number of test cases. Next 3t lines contain descriptions of test cases.

    The first line of each test case contains a single integer n (1≤n≤105) — the length of the binary strings.

    The next two lines contain two binary strings a and b of length n.

    It is guaranteed that the sum of n across all test cases does not exceed 105.

    Output

    For each test case, output an integer k (0≤k≤2n), followed by k integers p1,…,pk (1≤pi≤n). Here k is the number of operations you use and pi is the length of the prefix you flip in the i-th operation.

    Example
    input
    5
    2
    01
    10
    5
    01011
    11100
    2
    01
    01
    10
    0110011011
    1000110100
    1
    0
    1
    outputCopy
    3 1 2 1
    6 5 2 5 3 1 2
    0
    9 4 1 2 10 4 1 2 1 5
    1 1
    Note
    In the first test case, we have 01→11→00→10.

    In the second test case, we have 01011→00101→11101→01000→10100→00100→11100.

    In the third test case, the strings are already the same. Another solution is to flip the prefix of length 2, which will leave a unchanged.

    题目大意:

    给出 t 组样例,对于每组样例给出一个长度 n ,然后输入两个01串a b,然后有这样一个操作:选择长度为 i 的前缀,全部取反并逆置,询问能否在2n个操作以内使a b 相等,输出操作次数以及每次操作所选择的前缀。

    解题思路:

    要在2n 次操作完成,先把a变成全0序列。这样最多 n 次就可以了,然后再统计b变成全0序列的次数及操作,我们发现:该序列变成0的操作顺序倒过来即是全0序列还原的操作顺序,因为前面已经把a变成全0,再执行一次b全0的逆序操作即可 a == b,AC代码:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <vector>
    #include <queue>
    using namespace std;
    const int mod = 1e4;
    const int N = 1e5 + 50;
    const int inf = 0x3f3f3f3f;
    typedef long long ll;
    typedef pair<int, int> pii;
    string s, s1;
    int ans[N];
    int main()
    {
    	int t;
    	cin >> t;
    	while (t--)
    	{
    		int n;
    		vector<int > v1, v2;
    		cin >> n >> s >> s1;
    		s += '0';
    		s1 += '0';
    		for (int i = 1; i <= n; i ++)//统计a b 变成全0序列的操作次数和顺序
    		  if (s[i] != s[i - 1])
    		    v1.push_back(i);
    		for (int i = 1; i <= n; i ++)
    		  if (s1[i] != s1[i - 1])
    		    v2.push_back(i);
    		cout << (v1.size() + v2.size());
    		for (auto i : v1)
    		  cout << " " << i;
    		reverse(v2.begin(), v2.end());//b序列的操作顺序要逆序
    		for (auto i : v2)
    		  cout << " " << i;
    		cout << endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    python 3.x报错:No module named 'cookielib'或No module named 'urllib2'
    Xshell实现Windows和使用跳板机跳转的远程Linux互传文件
    Linux scp常用命令
    正则表达式
    [NBUT 1458 Teemo]区间第k大问题,划分树
    [hdu5416 CRB and Tree]树上路径异或和,dfs
    [vijos P1008 篝火晚会]置换
    [hdu5411 CRB and Puzzle]DP,矩阵快速幂
    [hdu4713 Permutation]DP
    [hdu4710 Balls Rearrangement]分段统计
  • 原文地址:https://www.cnblogs.com/Hayasaka/p/14294187.html
Copyright © 2011-2022 走看看