[Codeforces Round #373 DIV1E (CF718E)] Matvey's Birthday
来源:互联网 发布:田丰 阿里云 领英 编辑:程序博客网 时间:2024/06/08 04:47
题意
给定一个字符串,字符集大小为8
将每个位置当做一个点,相邻位置有长度为1的连边,任意相同字母的位置之间有长度为1的连边。求图的直径和直径的长度。
题解
求图的直径需要求任意两点间的最短路,这是不现实的。
设
其中
为什么
同时我们能得到这样的结论,树的直径小于字符集大小的二倍,即15,这个串就是一个例子aabbccddeeffgghh
枚举
|i−j|<16 ,此时直接由DIS(i,j)=min{|i−j|,min{dis(i,c)+1+dis(j,c)}} 求出|i−j|≥16 ,不能直接枚举j 了,此时DIS(i,j)=min{dis(i,c)+1+dis(j,c)}
现在设法求出
再设
预处理求出
再设数组
这样就能求出
时间复杂度
代码
/// by ztx/// blog.csdn.net/hzoi_ztx#define Rep(i,l,r) for(i=(l);i<=(r);i++)#define rep(i,l,r) for(i=(l);i< (r);i++)#define Rev(i,r,l) for(i=(r);i>=(l);i--)#define rev(i,r,l) for(i=(r);i> (l);i--)#define Each(i,v) for(i=v.begin();i!=v.end();i++)#define r(x) read(x)typedef long long ll ;typedef double lf ;int CH , NEG ;template <typename TP>inline void read(TP& ret) { ret = NEG = 0 ; while (CH=getchar() , CH<'!') ; if (CH == '-') NEG = true , CH = getchar() ; while (ret = ret*10+CH-'0' , CH=getchar() , CH>'!') ; if (NEG) ret = -ret ;}#define maxn 100010LL#define infi 0x3f3f3f3fLL#define id(c) (c+n+1)int n, ans;ll cnt;int dis[maxn][8], d[8][8], mask[maxn],c[8][256];char s[maxn];std::queue<int> q;inline void bfs(int x) { int i, u, v; dis[id(x)][x] = 0; Rep (i,1,n) if (s[i] == x) dis[i][x] = 0, q.push(i); while (!q.empty()) if (u = q.front(), q.pop(), u <= n) { if (v = u+1, 1<=v && v<=n && dis[v][x]==infi) { dis[v][x] = dis[u][x]+1, q.push(v); if (dis[id(s[v])][x] == infi) dis[id(s[v])][x] = dis[u][x]+1, q.push(id(s[v])); } if (v = u-1, 1<=v && v<=n && dis[v][x]==infi) { dis[v][x] = dis[u][x]+1, q.push(v); if (dis[id(s[v])][x] == infi) dis[id(s[v])][x] = dis[u][x]+1, q.push(id(s[v])); } } else Rep (i,1,n) if (id(s[i])==u && dis[i][x]==infi) dis[i][x] = dis[u][x]+1, q.push(i);}int main() { int i, j, k, l, now, x; r(n), scanf("%s", s+1); Rep (i,1,n) s[i] -= 'a'; memset(dis, 0x3f, sizeof dis); while (!q.empty()) q.pop(); rep (i,0,8) { bfs(i); rep (x,0,8) d[x][i] = dis[id(x)][i]; } Rep (i,1,n) rep (x,0,8) if (dis[i][x] > d[s[i]][x]) mask[i] |= 1<<x; Rep (i,1,n) { rep (j,std::max(i-15,1),i) { now = i-j; rep (k,0,8) now = std::min(now, dis[j][k]+dis[i][k]+1); if (now == ans) cnt ++ ; if (now > ans) ans = now, cnt = 1; } int t = i-16; if (t >= 1) c[s[t]][mask[t]] ++ ; rep (x,0,8) rep (k,0,256) if (c[x][k]) { now = infi; rep (l,0,8) now = std::min(now, d[x][l]+1+dis[i][l]+(k&(1<<l))); if (now == ans) cnt += c[x][k]; if (now > ans) ans = now, cnt = c[x][k]; } } printf("%d %lld\n", ans, cnt); END: getchar(), getchar(); return 0;}
0 0
- [Codeforces Round #373 DIV1E (CF718E)] Matvey's Birthday
- codeforces 718E. Matvey's Birthday
- [Codeforces Round #286 DIV1E (CF506E)] Mr. Kitayuta's Gift
- Codeforces Round #343 (Div. 2) Far Relative’s Birthday Cake
- [Codeforces Round #310 DIV1E (CF555E)] Case of Computer Network
- Codeforces Round #343 (Div. 2) A. Far Relative’s Birthday Cake
- Codeforces Round #343 (Div. 2) -A. Far Relative’s Birthday Cake(组合+模拟)
- CodeForces 827E Round$423 Div1E Solution:暴力的正确姿势
- CodeForces 248E Piglet's Birthday (概率)
- Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake
- Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake
- Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake
- codeforces Round#369 div2-E ZS and The Birthday Paradox
- hdu 5171 GTY's birthday gift (BestCoder Round #29)
- hdu5171 GTY's birthday gift(BestCoder Round #29 1002)
- BestCoder Round#29 1002 GTY's birthday gift
- Codeforces 629A Far Relative’s Birthday Cake
- CodeForces 629 A. Far Relative’s Birthday Cake(水~)
- freecodecamp 算法部分刷题笔记
- Leetcode 107. Binary Tree Level Order Traversal II
- struts2 demo
- windows8的BCD文件损坏无法进入的解决方法
- Spring中的一些术语
- [Codeforces Round #373 DIV1E (CF718E)] Matvey's Birthday
- <转载>图的存储方式
- 优酷路由宝 tf异常 解决办法
- java设计模式之责任链模式
- UITableView和UITableViewCell
- java 整合redis缓存 SSM 后台框架 rest接口 shiro maven
- c和Java在自加上的陷阱
- hdu3790 单点floyd松弛
- mysql 分表-横向,纵向