AtCoder Grand Contest 012 C:Tautonym Puzzle

题目传送门:https://agc012.contest.atcoder.jp/tasks/agc012_c

题目翻译

如果一个字符串是好的,那么这个字符串的前半部分和后半部分肯定一模一样。比如\(aa\)与\(bubobubo\)就是好的串,而空串,\(a\)与\(abcabcabc\)以及\(abba\)就不是好的。现在给你一个小于等于\(10^{12}\)的数字\(N\),要你求出一个字符串\(s\),使得这个串的\(2^{len}-1\)个子串里刚好有\(N\)个子串是好的。要求\(len\leqslant 200\)。

题解

我们先钦点空串是好的,\(s=X+Y\),\(X\)与\(Y\)分别是子串里只有空串是好串的字符串。假设\(c\)并没有出现在\(s\)里,我们用两种方式将\(c\)添加进\(s\)里去:

第一种:\(s'=cX+Yc\),这样的话\(s'\)的子串里好串的数量会比\(s\)里多\(1\)。

第二种:\(s'=Xc+Yc\),这样的话\(s'\)的子串里好串的数量会比\(s\)的多一倍。

只需要加一和乘二两种操作就可以凑出所有的数,我们把\(N\)二进制分解一下用双端队列搞搞就可以了。

时间复杂度:\(O(logN)\)

空间复杂度:\(O(len)\)

代码如下:

#include <deque>
#include <cstdio>
using namespace std;
typedef long long ll;

int m,num;
deque<int> s1,s2;
deque<int>::iterator it;

ll read() {
    ll x=0,f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    return x*f;
}

int main() {
    ll n=read()+1;//以为空串也是好串,所以这里要加一
    for(ll i=1;i<=n;i<<=1)m++;
    for(int i=m-2;~i;i--) {//初始有一个空串是好串,m-2是n的第二高的二进制位
        s1.push_back(++num),s2.push_back(num);
        if((n>>i)&1)s1.push_front(++num),s2.push_back(num);
    }
    printf("%d\n",(int)(s1.size()+s2.size()));
    for(it=s1.begin();it!=s1.end();it++)
        printf("%d ",(*it));
    for(it=s2.begin();it!=s2.end();it++)
        printf("%d ",(*it));
    return 0;
}

原文地址:https://www.cnblogs.com/AKMer/p/10043220.html

时间: 2024-08-30 13:54:46

AtCoder Grand Contest 012 C:Tautonym Puzzle的相关文章

AtCoder Grand Contest 014 E:Blue and Red Tree

题目传送门:https://agc014.contest.atcoder.jp/tasks/agc014_e 题目翻译 有一棵有\(N\)个点的树,初始时每条边都是蓝色的,每次你可以选择一条由蓝色边构成的简单路径,让这条路径的两个端点间连上一条红边,然后断开这条路径上的某条蓝边.这样做\(N-1\)次,就可以把原本的蓝树变成红树.现在给你蓝树和红树的样子,问你可不可能把给出的蓝树变成给出的红树.\(N\leqslant 10^5\) 题解 先膜一发大佬的题解:https://blog.csdn.

AtCoder Grand Contest 028 A:Two Abbreviations

题目传送门:https://agc028.contest.atcoder.jp/tasks/agc028_a 题目翻译 给你两个串\(s\)与\(t\),长度分别为\(n,m\).问你存不存在一个串长度为\(l\),\(l\)是\(n,m\)的公倍数,并且满足下面的条件: \(1\).对于第\(1\)位.第\(l/n+1\)位,第\(2*l/n+1\)位--第\((n-1)*l/n+1\)位的字符串依次拼接等于\(s\). \(2\).对于第\(1\)位.第\(l/m+1\)位,第\(2*l/m

AtCoder Grand Contest 025 Problem D

www.cnblogs.com/shaokele/ AtCoder Grand Contest 025 Problem D Time Limit: 2 Sec Memory Limit: 1024 MB Description Takahashi is doing a research on sets of points in a plane. Takahashi thinks a set \(S\) of points in a coordinate plane is a good set w

AtCoder Grand Contest 024 Problem E(动态规划)

www.cnblogs.com/shaokele/ AtCoder Grand Contest 024 Problem E Time Limit: 2 Sec Memory Limit: 1024 MB Description Find the number of the possible tuples of sequences (\(A_0,A_1,-,A_N\)) that satisfy all of the following conditions, modulo \(M\): ? Fo

AtCoder Grand Contest 011

AtCoder Grand Contest 011 upd:这篇咕了好久,前面几题是三周以前写的... AtCoder Grand Contest 011 A - Airport Bus 翻译 有\(n\)个乘客到达了飞机场,现在他们都要坐车离开机场.第\(i\)个乘客到达的时间是\(T_i\),一个乘客必须在\([T_i,T_i+k]\)时刻做到车,否则他会生气.一辆车最多可以坐\(C\)个人.问最少安排几辆车可以让所有人都不生气. 题解 从前往后贪心即可. #include<iostream

AtCoder Grand Contest 014

AtCoder Grand Contest 014 A - Cookie Exchanges 有三个人,分别有\(A,B,C\)块饼干,每次每个人都会把自己的饼干分成相等的两份然后给其他两个人.当其中有一个人的饼干数量是奇数的时候停止,求会进行几次这样子的操作,或者会永远进行下去. 首先无解的情况一定是三个数都是相等的偶数. 否则直接暴力模拟就行了.(盲猜答案不会很大) 证明一下答案的范围:不妨令\(A\le B\le C\),那么最大值和最小值之间的差就是\(C-A\),那么执行完一次操作之后

【Atcoder Grand Contest 020 E】 Encoding Subsets

Atcoder Grand Contest 020 E 题意:给一个\(0-1\)字符串,如果其中有一段重复,就可以表示成\((\)这一块的表示\(\times\)出现次数\()\). 问这个字符串的所有子集中有多少种表示方法. 思路:考虑\(dp(s)\)表示字符串\(s\)的答案. 那么我们得考虑第一个表示成的位置是什么. ①第一位就是表示的第一位,不参与循环.那么转移到\(dp(s.substr(1))\),并且如果这位是\(1\),那么乘上\(2\),因为这位可能是\(0\). ②一个前

AtCoder Grand Contest 016

AtCoder Grand Contest 016 A - Shrinking 你可以进行一个串的变换,把一个长度为\(n\)的串\(S\)可以变成长度为\(n-1\)的串\(T\),其中\(T_i\)要么是\(S_i\)要么是\(S_{i+1}\). 现在问你最少进行多少次这个操作,能够使最终得到的\(T\)只由一个字符构成. \(|S|\le 100\) 首先枚举最终字符是哪一个.那么首先在\(S\)末尾加上一个这个字符,那么这个最小步数等于对于所有位置而言,离它最近的枚举的字符到这个位置的

Atcoder Grand Contest 018 E - Sightseeing Plan

Atcoder Grand Contest 018 E - Sightseeing Plan 枚举从第二个矩形的 \((x_1,y_1)\) 进入,\((x_2,y_2)\) 出来,那么中间可以选的点的数量是 \(x_2+y_2-x_1-x_2+1\) ,也就是说对于每一条合法路线,从 \((x_1,y_1)\) 进入的贡献为 \(-x_1-x_2\) ,从 \((x_2,y_2)\) 出来的贡献为 \(x_2+y_2+1\) ,枚举一下第二个矩形边界上的点,我们只需要分别计算某个点到第一个矩形