bzoj2213: [Poi2011]Difference(思维题)
今天颓了一天T T
这题有两种写法...
①预处理出每种字符在原字符串中的位置,枚举两种字符作为最大值和最小值,把这两种字符的坐标归并排序,把最大值设为1,最小值设为-1,求最大子段和。注意因为最小值必须出现一次,所以要记录前缀最小值和次小值,答案只更新最小值出现次数不为0的一个,对于一个字符的出现次数用当前出现次数是否等于前缀最小值出现次数来判断就好了,复杂度O(50N)。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=,inf=1e9;
int n,ans,cnt;
int num[maxn],sum[maxn],last[maxn],pre[maxn],q[maxn];
char s[maxn];
inline void read(int &k)
{
int f=;k=;char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(c<=''&&c>='')k=k*+c-'',c=getchar();
k*=f;
}
void solve(int x,int y)
{
int mn1=,mn2=inf,frt1=;
for(int i=;i<=cnt;i++)
{
num[i]=num[i-]+(s[q[i]]-'a'==y);
sum[i]=sum[i-]+(s[q[i]]-'a'==x?:-);
if(num[i]==frt1)mn1=min(mn1,sum[i]);
else if(sum[i]<mn1)mn2=mn1,mn1=sum[i],frt1=num[i];
else if(sum[i]<mn2)mn2=sum[i];
if(num[i]-frt1>)ans=max(ans,sum[i]-mn1);
else ans=max(ans,sum[i]-mn2);
}
}
int main()
{
read(n);scanf("%s",s+);
for(int i=;i<=n;i++)pre[i]=last[s[i]-'a'],last[s[i]-'a']=i;
for(int i=;i<;i++)
for(int j=;j<i;j++)
if(last[i]&&last[j])
{
cnt=;int l1=last[i],l2=last[j];
while(l1||l2)
if(l1>l2)q[++cnt]=l1,l1=pre[l1];
else q[++cnt]=l2,l2=pre[l2];
solve(i,j);solve(j,i);
}
printf("%d\n",ans);
}
②对于两个字符计算答案为cnt[r][a]-cnt[l][a]-(cnt[r][b]-cnt[l][b]),可以转化成cnt[r][a]-cnt[r][b]和cnt[l][a]-cnt[l][b],于是我们只要记录一下当前值和前面的最小值,次小值,更新一个前缀y的数量不一样的就好了。因为每移动一格只会更新50个cnt,于是复杂度为O(50N)。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=,inf=1e9;
int n,ans;
int num[][],cnt[],g1[][],g2[][],f[][];
char s[maxn];
inline void read(int &k)
{
int f=;k=;char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(c<=''&&c>='')k=k*+c-'',c=getchar();
k*=f;
}
void solve(int x,int y)
{
if(num[x][y]==cnt[y])g1[x][y]=min(g1[x][y],f[x][y]);
else if(f[x][y]<g1[x][y])g2[x][y]=g1[x][y],g1[x][y]=f[x][y],num[x][y]=cnt[y];
else if(f[x][y]<g2[x][y])g2[x][y]=f[x][y];
if(num[x][y]!=cnt[y])ans=max(ans,f[x][y]-g1[x][y]);
else ans=max(ans,f[x][y]-g2[x][y]);
}
int main()
{
read(n);scanf("%s",s+);
memset(g2,,sizeof(g2));
for(int i=;i<=n;i++)
{
cnt[s[i]-'a']++;
for(int j=;j<;j++)
if(s[i]-'a'!=j)f[s[i]-'a'][j]++,solve(s[i]-'a',j),f[j][s[i]-'a']--,solve(j,s[i]-'a');
}
printf("%d\n",ans);
}
bzoj2213: [Poi2011]Difference(思维题)的更多相关文章
- BZOJ2213: [Poi2011]Difference
2213: [Poi2011]Difference Time Limit: 10 Sec Memory Limit: 32 MBSubmit: 343 Solved: 108[Submit][St ...
- BZOJ2213[Poi2011]Difference——DP
题目描述 A word consisting of lower-case letters of the English alphabet ('a'-'z') is given. We would li ...
- BZOJ2213 [Poi2011]Difference 【乱搞】
题目链接 BZOJ2213 题解 考虑任意一对点的贡献,单独拿出那些点所在位置 一个设为\(1\),一个设为\(-1\),从头到尾扫一遍维护前缀和,以及当前最小前缀和 两者相减更新答案 需要注意的是当 ...
- 【BZOJ2213】[Poi2011]Difference DP
[BZOJ2213][Poi2011]Difference Description A word consisting of lower-case letters of the English alp ...
- [bzoj2213][Poi2011]Difference_动态规划
Difference bzoj-2213 Poi-2011 题目大意:已知一个长度为n的由小写字母组成的字符串,求其中连续的一段,满足该段中出现最多的字母出现的个数减去该段中出现最少的字母出现的个数最 ...
- zoj 3778 Talented Chef(思维题)
题目 题意:一个人可以在一分钟同时进行m道菜的一个步骤,共有n道菜,每道菜各有xi个步骤,求做完的最短时间. 思路:一道很水的思维题, 根本不需要去 考虑模拟过程 以及先做那道菜(比赛的时候就是这么考 ...
- cf A. Inna and Pink Pony(思维题)
题目:http://codeforces.com/contest/374/problem/A 题意:求到达边界的最小步数.. 刚开始以为是 bfs,不过数据10^6太大了,肯定不是... 一个思维题, ...
- ZOJ 3829 贪心 思维题
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3829 现场做这道题的时候,感觉是思维题.自己智商不够.不敢搞,想着队友智商 ...
- 洛谷P4643 [国家集训队]阿狸和桃子的游戏(思维题+贪心)
思维题,好题 把每条边的边权平分到这条边的两个顶点上,之后就是个sb贪心了 正确性证明: 如果一条边的两个顶点被一个人选了,一整条边的贡献就凑齐了 如果分别被两个人选了,一作差就抵消了,相当于谁都没有 ...
随机推荐
- 使用Git提交与管理代码
要成为一个合格的码农,必须要有效对自己的代码进行管理,最近打算有空就整理一下自己以前写得代码,把不涉及实验室的机密的内容等放到github上,之前只知道git clone 别人的代码,希望有一天自己的 ...
- fastdfs+nginx+image_filter安装与生成缩略图
fastdfs简介 类似google FS的一个轻量级分布式文件系统,纯C实现,支持linux.FreeBSD等UNIX系统: 只能通过API访问,不支持POXIS: 文件不分块存储,上传的文件和OS ...
- elasticserach + kibana环境搭建
一.java环境安装: 1.安装jdk,点击下一步即可. 2.环境变量配置 1) 找到jdk安装目录:C:\Program Files\Java\jdk1.8.0_161 2) 配置环境变量 ①找到环 ...
- 华为笔试——C++特定位数比较
题目:特定位数比较 题目介绍:输入两行数据,第一行为 m 个正整数,以空格隔开:第二行为正整数 n ,且 n<= m:要求对第一行的数字的后三位大小进行排序,输出排行 n 的数字,其中,若不满三 ...
- Python--matplotlib 绘图可视化练手--折线图/条形图
最近学习matplotlib绘图可视化,感觉知识点比较多,边学习边记录. 对于数据可视化,个人建议Jupyter Notebook. 1.首先导包,设置环境 import pandas as pd i ...
- 第16次Scrum会议(10/28)【欢迎来怼】
一.小组信息 队名:欢迎来怼小组成员队长:田继平成员:李圆圆,葛美义,王伟东,姜珊,邵朔,冉华小组照片 二.开会信息 时间:2017/10/28 17:20~17:32,总计12min.地点:东北师范 ...
- “Hello World!”团队第十三次会议
今天是我们团队“Hello World!”团队召开的第十三次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 一.会议时间 2 ...
- C# 未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序。
在菜单 “项目”的最下面 工程属性 菜单,选择“生成”选项卡,将目标平台由“Amy CPU”或者“*64”改成“*86”.
- IIS 7.0 的 ASP.NET 应用程序生命周期概述
文章:IIS 7.0 的 ASP.NET 应用程序生命周期概述 地址:https://msdn.microsoft.com/zh-cn/library/bb470252(v=vs.100).aspx ...
- MDL详解
以下的虚拟内存可以理解成逻辑内存,因为我觉得只有这样才能讲通下面所有的东西.以下的“未分页”指没有为页进行编码. 以下为MDL结构体(我很郁闷,我在MSDN上没有找到这个结构体) typedef st ...