雅礼集训期间我好像考完试就开始划水了啊

给出k个长度相同的字符串,每个串有一个权值,选出一些串连成一个回文串.使得选中的串的总权值最大.

如果选一个串,必须同时选一个对称的串.还有一个特殊情况是可以在最中间放一个回文的串,求一下这种情况带来的额外的收入即可.

卡自然溢出hash....需要树同构那种奇奇怪怪的hash...

#include <cstdio>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
typedef unsigned long long ul;
const int maxn=100005;
int k,n;
string str[maxn];
ul Ha1[maxn],Ha2[maxn];
int w[maxn];
ul gethash1(string &A){
ul res=233;
for(int i=0;i<n;++i)res=(res*173323+A[i]+987)<<2^(res>>5);
return res;
}
ul gethash2(string &A){
ul res=233;
for(int i=n-1;i>=0;--i)res=(res*173323+A[i]+987)<<2^(res>>5);
return res;
}
ul Ha[maxn][2];
vector<int> a[maxn];
map<ul,int> dict;int tot=0;
map<ul,int> dict2;
long long work1(){
long long ans=0;
for(int i=1;i<=tot;++i){
if(Ha[i][0]==Ha[i][1]){
int SZ=a[i].size();
for(int j=SZ-1;j>=1&&a[i][j]+a[i][j-1]>0;j-=2){
ans+=a[i][j]+a[i][j-1];
}
}else if(Ha[i][0]<Ha[i][1]){
int t=dict[Ha[i][1]];
int SZ1=a[i].size(),SZ2=a[t].size();
for(int j=0;j<SZ1&&j<SZ2&&a[i][SZ1-j-1]+a[t][SZ2-j-1]>0;++j){
ans=ans+a[i][SZ1-j-1]+a[t][SZ2-j-1];
}
}
}
return ans;
}
long long work2(){
long long ans=0;
long long maxdelta=0;
for(int i=1;i<=tot;++i){
if(Ha[i][0]==Ha[i][1]){
int SZ=a[i].size();
if(SZ==1&&a[i][0]>maxdelta)maxdelta=a[i][0];
if(SZ>=2&&a[i][SZ-1]>maxdelta&&a[i][SZ-1]+a[i][SZ-2]<=0)maxdelta=a[i][SZ-1];
for(int j=SZ-1;j>=1&&a[i][j]+a[i][j-1]>0;j-=2){
ans+=a[i][j]+a[i][j-1];
if(a[i][j-1]<0&&-a[i][j-1]>maxdelta){
maxdelta=-a[i][j-1];
}
if(j>=3&&a[i][j-2]>maxdelta&&a[i][j-2]+a[i][j-3]<=0)maxdelta=a[i][j-2];
if(j==2&&a[i][0]>maxdelta)maxdelta=a[i][0];
}
}else if(Ha[i][0]<Ha[i][1]){
int t=dict[Ha[i][1]];
int SZ1=a[i].size(),SZ2=a[t].size();
for(int j=0;j<SZ1&&j<SZ2&&a[i][SZ1-j-1]+a[t][SZ2-j-1]>0;++j){
ans=ans+a[i][SZ1-j-1]+a[t][SZ2-j-1];
}
}
}
return ans+maxdelta;
}
int main(){
cin>>k>>n;
for(int i=1;i<=k;++i)cin>>str[i]>>w[i];
int t;
for(int i=1;i<=k;++i){
Ha1[i]=gethash1(str[i]);
Ha2[i]=gethash2(str[i]);
if(Ha1[i]==Ha2[i]){
if(dict2[Ha1[i]]){
t=dict2[Ha1[i]];
}else{
dict2[Ha1[i]]=t=++tot;
Ha[tot][0]=Ha[tot][1]=Ha1[i];
}
a[t].push_back(w[i]);
}else{
if(dict[Ha1[i]]){
t=dict[Ha1[i]];
}else{
dict[Ha1[i]]=t=++tot;
Ha[tot][0]=Ha1[i];Ha[tot][1]=Ha2[i];
}
a[t].push_back(w[i]);
}
}
long long ans=0;
for(int i=1;i<=tot;++i)sort(a[i].begin(),a[i].end());
printf("%lld\n",max(work1(),work2()));
return 0;
}

最新文章

  1. ASP.NET MVC搭建项目后台UI框架—4、tab多页签支持
  2. hdu-5992 Finding Hotels(kd-tree)
  3. AC日记——红与黑 codevs 2806
  4. unzip 命令使用
  5. Java学习-009-文件名称及路径获取实例及源代码
  6. 【python cookbook】【字符串与文本】7.定义实现最短匹配的正则表达式
  7. 通过cagradientLayer类封装uiimageview动画色度差
  8. 转载Expression Tree揭秘
  9. nyoj 528 找球号(三)(哈希)
  10. 使用Json实体类构建菜单数据
  11. Java菜鸟学习笔记--面向对象篇(十八):对象转型&amp;多态
  12. Debian 安装 vmware-tools 手记
  13. 深入Java集合学习系列:Hashtable的实现原理
  14. 实现容器的底层技术 - 每天5分钟玩转 Docker 容器技术(30)
  15. js监听input输入框值的实时变化实例
  16. Tcl 编译成tbc文件
  17. jmeter执行case结果插入DB生成报表和备份记录
  18. Dynamic Rankings || 动态/静态区间第k小(主席树)
  19. echarts 去掉网格线
  20. Swift3 - compare方法之ComparisonResult说明

热门文章

  1. su的使用与退出
  2. L013-linux基础正则表达式手把手实战讲解小节
  3. 五、Django之路由系统
  4. loadrunner-录制脚本,设置代理,参数化,校验点,关联
  5. and_or_not 逻辑运算符的操作注解!
  6. Struts2(一.基本介绍,环境搭建及需求分析)
  7. libCurl 初步认识 - cur easy
  8. Pearson Distance
  9. 工作在Amazon:为何晋升如此难?
  10. React Native 【学习总结】-【常用命令】