NOIP2018提高组省一冲奖班模测训练(五)

http://www.51nod.com/Contest/ContestDescription.html#!#contestId=79

今天有点浪……

第一题想了一个多小时想到了正解,然后敲到一半就去看lol总决赛了(恭喜IG!!!!!!)

然后就没有然后了……

A 循环

小D站在一个长度为n的环,环上的位置从0到n-1编号。位置0与位置n-1相邻。对于一个位置i,

小D只能跳到距离位置i不超过R[i]的位置上。

可以顺时针也可以逆时针跳。比如当n=5,R[1]=2时,小D可以跳到的位置集合为{4,0,1,2,3}。 一开始小D站在位置s,

他的终点是位置t。假设每跳一次需要单位时间1。你能求出小D跳到终点的最少需要时间吗?假如无解则输出-1。

注意因为输入规模比较大,R由以下方式生成。

R[i]=(R[i-1]×g+seed)mod~p

其中R[0],g,seed,p是给定的。

 

输入

第一行给定三个整数,n,s,t。
第二行给定四个整数R[0],g,seed,p。 【数据规模与约定】
对于20%的数据,n≤100
对于40%的数据,n≤1000
对于60%的数据,1≤n≤10^5
对于100%的数据,1≤n≤10^7,0≤s,t<n,1≤p≤n,0≤R[0],g,seed<p

输出

输出一行一个整数,表示最短时间。

输入样例

9 0 2
1 3 4 7

输出样例

2


刚看到这道题,我发现我好像很久很久很久以前做过???

不过肯定当时是抄题解的,印象不深,没怎么理解。

或者其实我没有做过,我自己yy罢了

首先我一开始去观察那个公式的性质

然后发现没什么规律

貌似就是为了输入方便……

然后我就考虑一个点所能达到的区间

画个图出来发现貌似是用贪心解决区间问题???

然后仔细想想好像不是

一个很显然的思路就是每次要跳到最远

然后我就画了几下,发现貌似之前搜过的点就不用再搜了

所以每一个点最多会被检查过一次,复杂度是O(n)的,可以过1e7的数据

但是我发现这涉及到跨越区间的问题(如从n-1跳到0),不好搞

而且s和t的大小关系也不确定

感觉不好实现,感觉会比较复杂

然后就硬着头皮去写,写了没多久,一看时间哇靠比赛要开始了,然后……

后来讲解我看到了标程的写法,在一些处理上非常有技巧性

我需要学习学习。代码有注释

#include<bits/stdc++.h>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std; const int MAXN = 1e7 + ;
int R[MAXN], a[MAXN], n, s, t;
int g, seed, p, ans;
bool val[MAXN]; int main()
{
scanf("%d%d%d%d%d%d%d", &n, &s, &t, &R[], &g, &seed, &p);
REP(i, , n) R[i] = (1ll * R[i-] * g + seed) % p;
REP(i, s, n) a[i - s] = R[i]; //a数组的作用就是把整个数组等价转化成以0为起点,方便后面处理
REP(i, , s) a[i - s + n] = R[i];
t = (t - s + n) % n; //注意这里s和t大小不确定 int l = , r = ;
_for(ans, , n)
{
if(l + n <= t || t <= r) { printf("%d\n", ans); return ; } //注意这里是或,可以画图理解
int pl = l, pr = r; //注意l是负的,但是一旦作为数组的下标就要加上n
_for(i, pl, )
{
if(val[i + n]) break; //val[i]表示i这个点有没有遍历过
l = min(l, i - a[i + n]), r = max(r, i + a[i + n]), val[i + n] = ;
}
for(int i = pr; i >= ; i--)
{
if(val[i]) break;
l = min(l, i - a[i]), r = max(r, i + a[i]), val[i] = ;
}
}
puts("-1"); return ;
}

小D的老师给了小D一大堆的字符串。具体来说,小D现在得到了N个字符串, 第i个字符串为S_i。对于小D来说,

他最喜欢的字符串就是回文串了。 一个串是回文串,当且仅当它倒过来和本身相同。比如abaaba倒过来还是abaaba,

而xyz倒过来是zyx,所以abaaba是回文串而xyz不是。 小D是个有创造力的孩子。他决定尝试把这些串两两拼接。

假如一次拼接后得到的串是回文的,他会非常开心。现在他想问你他最多能开心多少次?

形式化来说,小D想知道,有多少对二元组(i,j),满足i≠j,S_i+S_j是回文串。其中+表示字符串的前后拼接。

比如aa+ab=aaab。注意假如(i,j)和(j,i)都是满足条件的,那么答案算两次。

输入

第一行包含一个整数n。
接下来n行,每行给定一个字符串S_i。 【数据规模与约定】
对于20%的数据,字符串总长不超过2000。
对于40%的数据,n≤1000
另外有20%的数据,所有字符串长度均相同。
对于100%的数据,1≤n≤10^5,字符串总长度不超过10^5。字符串只包含小写字母。

输出

输出一个整数,表示答案。

输入样例

8
abaccabaab
accaba
abacc
ab
ba
aba
ccaba
abaaba

输出样例

14

这道题好艰辛……
写了N久 看到题目,字符总长已经提示会用到trie了
而且1e5要不是nlogn,要不是n
而有关字符串里面复杂度是O(n)的很容易想到trie
提示已经很明显了 正解是trie+哈希,非常的巧妙
我们考虑两个字符串
ab
ccba
这两个拼起来是abccba是一个回文串
那么回文串去掉两端也是回文串
所以我们把ccba拆成cc ba
可以用trie判断ab和ba,用哈希判断cc是否是回文串(正串与反串的哈希值相等即为回文串)
这是大致思路
那么我们可以预处理每个串的每个前缀是不是回文串,用哈希,复杂度为字符总数
然后每次把当前串倒着去trie上遍历,如果遍历一个位置,之前是回文串,那么更新答案
然后再加入当前串
如果我们按照下标的顺序去这样处理的话
可以发现会漏掉一些情况
如果这样得出的字符满足
i < j ,i + j是回文串
显然还有三种情况
i < j ,j + i是回文串
i > j ,i + j是回文串
i > j ,j + i是回文串
对于i > j可以改变枚举的顺序
对于j+i,可以把串取反再去做(这个时候如果两个串长度相同会算两次,要特判)
因为如果j + i是回文串
那么i取反的ii,j取反的jj
ii + jj也是回文串
很神奇,其实可以证明
比如ab + ccba
取反交换相加即
abcc + ba
也是回文串
#include<bits/stdc++.h>
#define REP(i, a, b) for(register int i = (a); i < (b); i++)
#define _for(i, a, b) for(register int i = (a); i <= (b); i++)
using namespace std; typedef unsigned long long ull;
const int MAXN = 1e5 + ;
const int base = ; int trie[MAXN][], tot;
int flag[MAXN], n;
string s[MAXN];
ull p[MAXN], hash[MAXN][], cnt[MAXN], ans; void init()
{
tot = ;
memset(cnt, , sizeof(cnt));
memset(trie, , sizeof(trie));
} void Insert(string s)
{
int p = , len = s.length();
REP(i, , len)
{
int ch = s[i] - 'a';
if(!trie[p][ch]) trie[p][ch] = ++tot;
p = trie[p][ch];
}
cnt[p]++;
} void Search(string s, int op)
{
int p = , len = s.length();
for(int i = len - ; i >= ; i--)
{
int ch = s[i] - 'a';
if(!trie[p][ch]) return;
p = trie[p][ch];
if((op || i) && (!i || flag[i - ])) ans += cnt[p];
}
} inline ull val(int l, int r, int k)
{
return hash[r][k] - (l - < ? : hash[l-][k]) * p[r - l + ];
} void solve(int op)
{
init();
_for(k, , n)
{
string str = s[k];
int len = str.length();
hash[][] = str[] - 'a';
hash[][] = str[len-] - 'a'; REP(i, , len)
{
hash[i][] = hash[i-][] * base + str[i] - 'a';
hash[i][] = hash[i-][] * base + str[len-i-] - 'a';
}
REP(i, , len) flag[i] = (val(, i, ) == val(len - i - , len - , ) ? : ); Search(str, op);
Insert(str);
}
} int main()
{
ios::sync_with_stdio(false);
cin >> n;
_for(i, , n) cin >> s[i];
p[] = ; _for(i, , MAXN) p[i] = p[i-] * base; solve();
reverse(s + , s + n + ); solve();
_for(i, , n) reverse(s[i].begin(), s[i].end()); solve();
reverse(s + , s + n + ); solve(); printf("%llu\n", ans);
return ;
}
第三题不会,不想改了……


NOIP2018提高组省一冲奖班模测训练(五)的更多相关文章

  1. NOIP2018提高组省一冲奖班模测训练(六)

    NOIP2018提高组省一冲奖班模测训练(六) https://www.51nod.com/Contest/ContestDescription.html#!#contestId=80 20分钟AC掉 ...

  2. NOIP2018提高组省一冲奖班模测训练(四)

    NOIP2018提高组省一冲奖班模测训练(四) 这次比赛只AC了第一题,而且花了40多分钟,貌似是A掉第一题里面最晚的 而且还有一个半小时我就放弃了…… 下次即使想不出也要坚持到最后 第二题没思路 第 ...

  3. NOIP2018提高组省一冲奖班模测训练(三)

    NOIP2018提高组省一冲奖班模测训练(三) 自己按照noip的方式考,只在最后一两分钟交了一次 第一题过了,对拍拍到尾. 第二题不会.考试时往组合计数的方向想,推公式,推了一个多小时,大脑爆炸,还 ...

  4. NOIP2018提高组省一冲奖班模测训练(二)

    比赛链接 NOIP2018提高组省一冲奖班模测训练(二) 今天发挥正常,昨天不在状态…… 花了很久A了第一题 第二题打了30分暴力 第三题投机取巧输出test1答案(连暴力都不知道怎么打,太弱了) 2 ...

  5. NOIP2018提高组省一冲奖班模测训练(一)

    比赛链接 https://www.51nod.com/contest/problemList.html#!contestId=72&randomCode=147206 这次考试的题非常有质量 ...

  6. [51Nod]NOIP2018提高组省一冲奖班模测训练(三) 题解

    链接 A.Anan的派对 题意:Anan想举办一个派对.Anan的朋友总共有 n 人.第i个人如果参加派对会得到 \(c_i\) 的快乐值,除他自己外每多一个人参加他会减少 \(d_i\) 的快乐值. ...

  7. [51Nod]NOIP2018提高组省一冲奖班模测训练(四)翻车记+题解

    链接 下午5点的时候,突然想起来有这个比赛,看看还有一个小时,打算来AK一下,结果因为最近智商越来越低,翻车了,我还是太菜了.上来10分钟先切掉了C和A,结果卡在了B题,唉. A.砍树 一眼题,两遍树 ...

  8. [51Nod]NOIP2018提高组省一冲奖班模测训练(二)

    http://www.51nod.com/contest/problemList.html#!contestId=73&randomCode=4408520896354389006 还是原题大 ...

  9. [51Nod]NOIP2018提高组省一冲奖班模测训练(一)题解

    http://www.51nod.com/contest/problemList.html#!contestId=72&randomCode=147206 原题水题大赛.. A.珂朵莉的旅行 ...

随机推荐

  1. POJ 1175

    //本来写了个和1021相同的HASH,但没过,于是,抱着侥幸的心理,把它变成距离的四次方, //我就呵呵了... //这个题,完全靠概率.当然了,如果是把图翻转来比较,也是可以的.但好像很麻烦.. ...

  2. [React] Refactor componentWillReceiveProps() to getDerivedStateFromProps() in React 16.3

    The componentWillReceiveProps() method is being deprecated in future version of React (17). Many of ...

  3. OLR文件丢失的恢复

    11.2.0.1的RAC中,rac1和rac2 一.OLR有备份的情况 1.手动将rac1中的olr重命名,模拟丢失 mv rac1.olr rac1.olr.test 2.重新启动crs ./crs ...

  4. UVA 4855 Hyper Box

    You live in the universe X where all the physical laws and constants are different from ours. For ex ...

  5. POJ 3126 Prime Path SPFA

    http://poj.org/problem? id=3126 题目大意: 给你两个四位的素数s和t,要求每次改变一个数字.使得改变后的数字也为素数,求s变化到t的最少变化次数. 思路: 首先求出全部 ...

  6. ActionFilterAttribute

    https://msdn.microsoft.com/en-us/library/system.web.mvc.actionfilterattribute.onactionexecuting(v=vs ...

  7. day63-webservice 11.cxf整合spring

    如果我们有Spring配置文件,怎么把WebService整合到Spring里面,用Ioc容器来管理这个Bean. 做项目的时候一般都是分层:Dao层.Service层.Service层要调Dao层, ...

  8. 8、List接口的特点及其相关功能

    /* * Collection * |--List * 元素有序(指的是存储顺序和取出顺序是否一致),可重复. * |--Set * 元素无序,唯一. */ /* * List的特有功能: * A:添 ...

  9. 深入分析setContentView

    在网络层,互联网提供所有应用程序都要使用的两种类型的服务,尽管目前理解这些服务的细节并不重要,但在所有TCP/IP概述中,都不能忽略他们: 无连接分组交付服务(Connectionless Packe ...

  10. JavaScrip——插入地图

    具体操作步骤:1.百度搜索:百度地图生成器 2.打开第一个,复制网址http://api.map.baidu.com/lbsapi/creatmap/index.html,打开3.页面显示为 4.根据 ...