ACM-ICPC 2018 南京赛区网络预赛 I Skr (马拉车+hash去重)或(回文树)
https://nanti.jisuanke.com/t/30998
题意
给一串由0..9组成的数字字符串,求所有不同回文串的权值和。比如说“1121”这个串中有“1”,“2”,“11”,“121”三种回文串,他们的权值分别是1,2,11,121。最终输出ans=135。
分析
第一次知道马拉车是manacher。。。涨姿势了
在马拉车进行的过程中,进行子回文串的统计去重。
这里的哈希去重方法重点学习理解。
- #include <iostream>
- #include <cstdio>
- #include <cstdlib>
- #include <cstring>
- #include <string>
- #include <algorithm>
- #include <cmath>
- #include <ctime>
- #include <vector>
- #include <queue>
- #include <map>
- #include <stack>
- #include <set>
- #include <bitset>
- using namespace std;
- typedef long long ll;
- typedef unsigned long long ull;
- #define ms(a, b) memset(a, b, sizeof(a))
- #define pb push_back
- #define mp make_pair
- #define pii pair<int, int>
- //#define eps 0.0000000001
- #define IOS ios::sync_with_stdio(0);cin.tie(0);
- #define random(a, b) rand()*rand()%(b-a+1)+a
- #define pi acos(-1)
- //const ll INF = 0x3f3f3f3f3f3f3f3fll;
- const int inf = 0x3f3f3f3f;
- const int maxn = 2e6 + ;
- const int maxm = +;
- const int mod = ;
- ull base=;
- ull p[maxn<<],has[maxn<<];
- ll pw[maxn<<],sum[maxn<<];
- const int MOD=;
- int head[maxn<<],nxt[maxn<<],cnt=;
- ull val[maxn];
- bool exist(ull now){
- int u=now%MOD;
- for(int i=head[u];i;i=nxt[i]){
- if(val[i]==now) return true;
- }
- val[cnt]=now;
- nxt[cnt]=head[u];
- head[u]=cnt++;
- return false;
- }
- ull gethas(int l,int r){
- return has[r]-has[l-]*p[r-l+];
- }
- ll solve(int l,int r){
- ull tmp=gethas(l,r);
- if(exist(tmp)) return ;
- ll ans=(sum[r]-sum[l-]*pw[(r-l++)/]%mod+mod)%mod;
- return ans;
- }
- char s[maxn];
- char Ma[maxn<<];
- int Mp[maxn<<];
- ll Manacher(char s[],int len){
- int l=;
- Ma[l++]='$';
- Ma[l++]='#';
- for(int i=;i<len;i++){
- Ma[l++]=s[i];
- Ma[l++]='#';
- }
- Ma[l]=;
- pw[]=p[]=;
- has[]=sum[]=;
- for(int i=;i<=l;i++){
- p[i]=p[i-]*base;
- has[i]=has[i-]*base+Ma[i];
- pw[i]=pw[i-]*%mod;
- if(Ma[i]>=''&&Ma[i]<=''){
- sum[i]=(sum[i-]*+Ma[i]-'')%mod;
- }else{
- sum[i]=sum[i-];
- }
- }
- ll ans=;
- int mx=,id=;
- for(int i=;i<l;i++){
- if(Ma[i]!='#') ans=(ans+solve(i,i))%mod;
- Mp[i]=mx>i?min(Mp[*id-i],mx-i):;
- while(Ma[i+Mp[i]]==Ma[i-Mp[i]]){
- if(Ma[i+Mp[i]]!='#') ans=(ans+solve(i-Mp[i],i+Mp[i]))%mod;
- Mp[i]++;
- }
- if(mx<i+Mp[i]){
- mx=i+Mp[i];
- id=i;
- }
- }
- return ans;
- }
- int main() {
- #ifdef LOCAL
- freopen("in.txt", "r", stdin);
- // freopen("input.txt", "w", stdout);
- #endif
- scanf("%s",s);
- int len=strlen(s);
- printf("%lld\n",Manacher(s,len));
- return ;
- }
回文树的做法是先构建一颗回文树,然后dfs奇偶节点,当前节点的所代表的数字=当前添加的数字*pow(10,当前回文串长度-1) +他父亲的数字*10+当前添加的数字。
比如:33->1331 就是1*1000+33+1。此外有点卡空间,注意内存使用
- #include <iostream>
- #include <cstdio>
- #include <cstdlib>
- #include <cstring>
- #include <string>
- #include <algorithm>
- #include <cmath>
- #include <ctime>
- #include <vector>
- #include <queue>
- #include <map>
- #include <stack>
- #include <set>
- #include <bitset>
- using namespace std;
- typedef long long ll;
- typedef unsigned long long ull;
- #define ms(a, b) memset(a, b, sizeof(a))
- #define pb push_back
- #define mp make_pair
- #define pii pair<int, int>
- //#define eps 0.0000000001
- #define IOS ios::sync_with_stdio(0);cin.tie(0);
- #define random(a, b) rand()*rand()%(b-a+1)+a
- #define pi acos(-1)
- //const ll INF = 0x3f3f3f3f3f3f3f3fll;
- const int inf = 0x3f3f3f3f;
- const int maxn = 2e6 + ;
- const int maxm = +;
- const int mod = 1e9+;
- struct PAM{
- int nxt[maxn][];
- int fail[maxn];
- int cnt[maxn];
- int num[maxn];
- int len[maxn];
- int s[maxn];
- int last,n,p;
- int newnode(int w){
- for(int i=;i<;i++) nxt[p][i]=;
- num[p]=cnt[p]=;
- len[p]=w;
- return p++;
- }
- void init(){
- n=last=p=;
- newnode();
- newnode(-);
- s[n]=-;
- fail[]=;
- }
- int get_fail(int x){
- while(s[n-len[x]-]!=s[n]) x=fail[x];
- return x;
- }
- void add(int c){
- c-='';
- s[++n]=c;
- int cur=get_fail(last);
- if(!nxt[cur][c]){
- int now=newnode(len[cur]+);
- fail[now]=nxt[get_fail(fail[cur])][c];
- nxt[cur][c]=now;
- num[now]=num[fail[now]]+;
- }
- last=nxt[cur][c];
- cnt[last]++;
- }
- void Count(){
- for(int i=p-;i>=;i--) cnt[fail[i]]+=cnt[i];
- }
- };
- PAM pam;
- char s[maxn];
- ll odd=;
- ll even=;
- ll qpow(ll a,ll b){
- ll res=;
- while(b){
- if(b&) res=a*res%mod;
- b>>=;
- a=a*a%mod;
- }
- return res;
- }
- void dfs_odd(int x,ll fa){
- for(int i=;i<=;i++){
- if(pam.nxt[x][i]){
- ll cur;
- if(pam.len[pam.nxt[x][i]]==){
- odd=(i+odd)%mod;
- cur=i;
- }else{
- cur=(i*qpow(,pam.len[pam.nxt[x][i]]-)%mod+i+fa*%mod)%mod;
- odd=(odd+cur%mod)%mod;
- }
- dfs_odd(pam.nxt[x][i],cur);
- }
- }
- }
- void dfs_even(int x,ll fa){
- for(int i=;i<=;i++){
- if(pam.nxt[x][i]){
- ll cur=(i*qpow(,pam.len[pam.nxt[x][i]]-)%mod+i+fa*%mod)%mod;
- even=(even+cur)%mod;
- dfs_even(pam.nxt[x][i],cur);
- }
- }
- }
- int main() {
- #ifdef LOCAL
- freopen("in.txt", "r", stdin);
- // freopen("input.txt", "w", stdout);
- #endif
- pam.init();
- scanf("%s",s);
- int len=strlen(s);
- for(int i=;i<len;i++) pam.add(s[i]);
- dfs_odd(,);
- dfs_even(,);
- printf("%lld\n",(odd+even)%mod);
- return ;
- }
ACM-ICPC 2018 南京赛区网络预赛 I Skr (马拉车+hash去重)或(回文树)的更多相关文章
- ACM-ICPC 2018 南京赛区网络预赛 G Lpl and Energy-saving Lamps(模拟+线段树)
https://nanti.jisuanke.com/t/30996 题意 每天增加m个灯泡,n个房间,能一次性换就换,模拟换灯泡过程.询问第几天的状态 分析 离线做,按题意模拟.比赛时线段树写挫了. ...
- ACM-ICPC 2018 南京赛区网络预赛 I. Skr(回文树)
题意 https://nanti.jisuanke.com/t/A1955 求所有本质不同的回文串转成数后的和. 思路 如果了解回文树的构造原理,那么这题就很简单了,回文树每个结点代表一个回文串,每添 ...
- ACM-ICPC 2018 南京赛区网络预赛 J.sum
A square-free integer is an integer which is indivisible by any square number except 11. For example ...
- ACM-ICPC 2018 南京赛区网络预赛 E题
ACM-ICPC 2018 南京赛区网络预赛 E题 题目链接: https://nanti.jisuanke.com/t/30994 Dlsj is competing in a contest wi ...
- ACM-ICPC 2018 南京赛区网络预赛B
题目链接:https://nanti.jisuanke.com/t/30991 Feeling hungry, a cute hamster decides to order some take-aw ...
- 计蒜客 30999.Sum-筛无平方因数的数 (ACM-ICPC 2018 南京赛区网络预赛 J)
J. Sum 26.87% 1000ms 512000K A square-free integer is an integer which is indivisible by any squar ...
- 计蒜客 30996.Lpl and Energy-saving Lamps-线段树(区间满足条件最靠左的值) (ACM-ICPC 2018 南京赛区网络预赛 G)
G. Lpl and Energy-saving Lamps 42.07% 1000ms 65536K During tea-drinking, princess, amongst other t ...
- 计蒜客 30990.An Olympian Math Problem-数学公式题 (ACM-ICPC 2018 南京赛区网络预赛 A)
A. An Olympian Math Problem 54.28% 1000ms 65536K Alice, a student of grade 66, is thinking about a ...
- ACM-ICPC 2018 南京赛区网络预赛 B. The writing on the wall
题目链接:https://nanti.jisuanke.com/t/30991 2000ms 262144K Feeling hungry, a cute hamster decides to o ...
随机推荐
- 【XSY2762】插线板 分块
题目大意 有\(n\)个插线板,每个插线板会在\(l_i\)时刻初插入到队列中(队列是按插线板的编号排序的),\(r_i\)时刻末移除. 插入一个插线板时会对当前所有接在队列中这个插线的下一个插线板上 ...
- 【XSY2751】Mythological IV 线性插值
题目描述 已知\(f(x)\)为\(k\)次多项式. 给你\(f(0),f(1),\ldots,f(k)\),求 \[ \sum_{i=1}^nf(i)q^i \] \(k\leq 500000,n\ ...
- 搭建web定时任务管理平台
需要安装mysql及gityum -y install git mysql-server 下载安装go官网:https://golang.org/dl/wget https://redirector. ...
- mysql5.6做单向主从复制Replication
原理场景:MySQL从3.23版本开始提供复制功能.指的是将主数据库的DDL和DML操作通过二进制日志传到从服务器(也叫从库),然后在从库上对这些日志重新执行, 从而使得从库和主库的数据保持同步. 优 ...
- 牛客练习赛28 B数据结构(线段树)
链接:https://www.nowcoder.com/acm/contest/200/B来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言5242 ...
- A1128. N Queens Puzzle
The "eight queens puzzle" is the problem of placing eight chess queens on an 8×8 chessboar ...
- 【CF1141G】Privatization of Roads in Treeland
题目大意:给定一个 N 个点的无根树,现给这个树进行染色.定义一个节点是坏点,若满足与该节点相连的至少两条边是相同的颜色,求至多有 k 个坏点的情况下最少需要几种颜色才能进行合法染色. 题解:考虑一个 ...
- T4 反射实体模型生成代码(Demo)
1.新建一个T4 Script <#@ template language="C#" debug="True" #> <#@ output ...
- (递推)codeVs1011 && 洛谷P1028 数的计算
题目描述 Description 我们要求找出具有下列性质数的个数(包含输入的自然数n): 先输入一个自然数n(n<=1000),然后对此自然数按照如下方法进行处理: 1. 不 ...
- vue实现购物车和地址选配
参考文献 vue.js官网 项目演示:数据渲染,格式化数据,点击加,减号自动加减 项目准备 1. 项目css和js文件 https://github.com/4561231/hello ...