2019.10.31模拟赛

说在前面

考场遇见原题???
上午刚做的 下午就\(T3\)考到了\(2333\)
然而还是因为忘了取模挂了28分

T1 Dove下跳棋

数据太水输出n-1可得90
Dove 喜爱下跳棋,在传统的跳棋基础之上,Dove 又延伸出了许多别的玩法。Dove 以一个一维数轴为棋盘下跳棋,总共会移动棋子?? ? 1 次。因为讨厌没有规律,所以Dove 每次只会恰好把棋子向右移动?? 个格子。
Cicada 送给了Dove 一个长度为?? 的数列{??},为了表示感谢,Dove 打算以Cicada
送给他的序列{??} 为基础下跳棋。具体的,Dove 将会把棋子从编号为??1 的格子出发,在第?? 次移动后,把棋子移动到编号为????+1 的格子。显然Cicada 送给他的{??} 有可能不满足Dove 要求的条件,Dove 想知道,最少需要修改多少个???? 的值,才能使得这个数列{??} 是满足Dove 需要的移动棋子的要求的。

你以为从\(a1\)开始直接计算?不这是错的。\(a1\)是可以修改的。
正解:我们推一波式子:
\(a_i + (j - i) * k = a_j\)
\(a_i - k * i = a_j - k * j\)
所以只要把这个数扔进map,相同的就是可以到达的。
找到最多的可以到的数,其余的就是要修改的。
这场比赛开c++11, unordered_map快到飞起。

unordered_map<int,int> mp;
signed main()
{
    freopen("chess.in", "r", stdin);
    freopen("chess.out", "w", stdout);
    poread(n), poread(k);
    for(register int i = 1; i <= n; ++i) poread(a[i]);
    for(register int i = 1; i <= n; ++i) ++mp[a[i] - k * i];
    register int ans = INT_MAX;
    for(register int i = 1; i <= n; ++i) ans = min(n - mp[a[i] - k * i],ans);
    printf("%lld\n", ans);
    return 0;
}

T2 Cicada爱子串

作为一个熟练的算法竞赛选手,Cicada 喜爱研究字符串问题。特别的,他尤其喜爱研究字符串中的子串问题。
某日,Cicada 在研究这样一道题目。首先对于一个字符串??,我们定义其第?? 个字符到第?? 个字符构成的子串为????,??。同时我们定义函数??(??, ??, ??) 表示将字符串?? 的第?? 到第??个字符删去后构成的字符串,??(??, ??, ??) 表示将?? 插入?? 的第?? 个字符之后构成的字符串。
Cicada 想知道,对于一个给定的长度为?? 的字符串??,有多少个三元组(??, ??, ??),满足?? = ??(??(??, ??, ??), ??, ????,??)。
这题考场失智少算了情况。
正解:
找到字符串的循环节,每一个基本序列可以放到循环节的每个地方,加起来就是答案。
\(f[l][r]\)表示\(l,r\)这段区间最小循环节的循环次数,考虑贡献。
对于\(l,r\)这段区间,我们可以在\(f[l][r]-1\)个位置把区间断成两段,把左边区间放到右边区间的右侧,或者把右边区间放到左边区间的左侧,并且加上自己放到自己位置产生的\(1\)的贡献。
这么做不会记重因为更多的区间分割可能包含在了更小的区间里。

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 6e3 + 5;
const int MOD = 1e9 + 7;
const int HS = 17171;
unsigned long long has[MAXN], sh[MAXN];
char s[MAXN];
int f[MAXN][MAXN], v[MAXN];
int n;
inline unsigned long long str(int l, int r)
{
    return has[r] - has[l - 1] * sh[r - l + 1];
}
int main()
{
    scanf("%s", s + 1);
    n = strlen(s + 1);
    sh[0] = 1;
    for(register int i = 1; i <= n; ++i)
        sh[i] = sh[i - 1] * HS;
    for(register int i = 1; i <= n; ++i)
        has[i] = (has[i - 1] * HS + s[i]);
    for(register int len = 1; len <= n; ++len)
    {
        memset(v, 0, sizeof(v));
        for(register int r = len; r <= n; ++r)
        {
            v[r] = 1;
            if(r >= (len << 1))
                if(str(r - len + 1,r) == str(r - len - len + 1, r - len))
                    v[r] += v[r - len];
            f[r - v[r] * len + 1][r] = max(f[r - v[r] * len + 1][r], v[r]);
        }
    }
    register long long ans = 0;
    for(register int l = 1; l <= n; ++l)
    {
        for(register int r = n; r >= l; --r)
        {
            f[l][r] = max(f[l][r], 1);
            register int len = (r - l + 1) / f[l][r];
            if(l + len <= r)
                f[l + len][r] = max(f[l + len][r], f[l][r] - 1);
            if(r - len >= l)
                f[l][r - len] = max(f[l][r - len], f[l][r] - 1);
            ans += 1 + ((f[l][r] - 1) << 1);
        }
    }
    cerr << ans << endl;
    cout << ans << endl;
    return 0;
}

T3

昨天刚写了博客,直接看吧。
code festival 2016 qual C E题 順列辞書

原文地址:https://www.cnblogs.com/Shiina-Rikka/p/11775105.html

时间: 2024-07-29 12:49:26

2019.10.31模拟赛的相关文章

10.31 模拟赛

10.31 模拟赛 A LIS 考虑每个数字前从 $ m $ 降序构造到 $ a_i $ 即可. #include <iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<vector> using namespace std; #define MAXN 300006 int n , m , k; int A[MAXN]; vector<int&g

2019.10.24模拟赛赛后总结

本文原创,如果有不到位的地方欢迎通过右下角的按钮私信我! A.Icow Player 题目描述 被无止境的农活压榨得筋疲力尽后,Farmer John打算用他在MP3播放器市场新买的iCow来听些音乐,放松一下.FJ的iCow里存了N(1 <= N <= 1,000)首曲子,按1..N依次编号.至于曲子播放的顺序,则是按一个Farmer John自己设计的算法来决定: * 第i首曲子有一个初始权值R_i(1 <= R_i <= 10,000). * 当一首曲子播放完毕,接下来播放的

2019.10.18模拟赛T3

题目大意: 求$\sum\limits_{i=1}^n\sum\limits_{j=1}^n[lcm(i,j)>n](n\leq 10^{10})$的值. 题解: 这题貌似有n多种做法... 为了更好统计,把原式变为$n^2-\sum\limits_{i=1}^n\sum\limits_{j=1}^n[lcm(i,j)\leq n]$. 然后开始毒瘤... 首先,考虑枚举$lcm(i,j)$,设为$d$,计算有多少对$i.j$的最小公倍数为$d$. 设$i=p_1^{a_1}p_2^{a_2}\

2019.10.26模拟赛

T1 序列 给定一长度为\(n\)的序列\(s\),定义其健美值为:\[\sum\limits_{i=1}^{n}|s_i - i|\]因为 zzq 喜欢健美,所以 zzq 希望减小\(s\)的健美值,以衬托 zzq 的健美.为了达到 zzq 的目的,zzq 希望你对序列进行旋转操作,一次旋转操作可以使序列中的所有元素前移一位,并使\(s_1\)移动到\(s_n\). 可以进行任意次旋转操作,zzq 希望旋转后的健美值最小,请找出这个最小值. SOV 智商检测题 我们发现对于每个数,移动每一次会

[10.31模拟赛]T3

Description 青青草原上有\(k\)只羊,他们聚集在包包大人的家里,举办一年一度的表彰大会,在这次的表彰大会中,包包大人让羊们按自己的贡献从小到大排成一排,以便于发放奖金. 每只羊都会得到数值在\(1\)~\(n\)的奖金,并且第i只羊的奖金应为第\(i+1\)只羊的约数(即满足\(ai|ai+1\)). 现在包包大人想知道一共有多少种不同的发放奖金的方式(两种发放奖金的方式不同是指在两种发放奖金的方式中存在某只羊拿到的奖金不同) Input 一行两个正整数\(n\),\(k\),满足

2019.10.22模拟赛

T1 合并集合 有\(n\)个集合,第\(i\)个集合记为\(S_i\),集合按环状排列,即第\(i + 1\)个集合右边是第\(i\)个集合,第\(n\)个集合右边是第\(i\)个集合. 一开始每个集合里只有一个数,每次你可以选择两个相邻的集合\(S,T\),然后合并成\(S \cup T\),之后你可以获得收益\(|S| \times |T|\),其中\(|S|\)表示集合\(S\)的元素个数. 你需要一直进行以上的操作直到只剩一个集合为止,求能获得的最大的收益之和. 断环为链,复制两倍区间

2019.10.24模拟赛

T1 古代龙人的谜题 Mark Douglas 是一名调查员.他接受了「调查古代龙人」的任务.经过千辛万苦,Mark 终于找到了一位古代龙人.Mark 找到他时,他正在摆弄一些秘药,其中一些药丸由于是从很久以前流传下来的,发出了独特的光泽.古代龙人告诉了 Mark 一些他想知道的事情,看了看手中的秘药,决定考一考这位来访者. 古代龙人手中共有\(n\)粒秘药,我们可以用\(1\)表示「古老的秘药」,其余的用\(0\)表示.他将它们排成一列.古代龙人认为平衡是美的,于是他问 Mark 能选出多少个

离线赛 2019.10.31

2019.10.30 \[ Ameiyo \] A: 地精部落 : Dp , 前缀和优化 Dp B: 深入虎穴 : 图,结论题 C: 教义问答手册 : 分治,分块,Dp A 挺简单的一道 Dp ...看 这个博客 . B 其实可以用 dijsktra 做这道题,但是每次用来更新的都是自己的次小值. 因为当你走到当前点时,老虎会让你不能走最小值,所以是用次小值更新. 每次也是拿次小值最小的点出来更新. ll mi[N][2]; struct NODE { int id; ll w; inline

10.2模拟赛总结

10.2 模拟赛总结 T1. 数位dp: 一个非常非常非常非常显然的数位 DP \([L,R] = [1,R]-[1,L-1]\) 所以是分别求两次小于等于某个数字的方案数 \(f(i,j,k)\) 表示从低位数起的第 \(i\) 位,按照规则计算后答案为 \(j\quad (j=0,1)\) \(k\) 表示只考虑后面结尾和 \(lmt\)后面几位 的大小关系 \((k=0,1)\) 考虑第 \(i+1\) 位,算一下新构成的数字并判断下大小就可以了 注意到 \(L,R\) 数据范围特别大,需