题意:

给定n个字符串S1,S2,S3,...,Sn,把它们排序

设排序结果为Sp1,Sp2,Sp3,...,Spn

现在给定q个任务,每个任务的格式都是"要求在排序结果中Sa恰好在Sb前一个"

你排出的串满足第i个任务,就可以得到2^i(2的i次方)的奖励

现在有两个问题:

1.求相邻两项LCP平方和W的最大值

2.求出当W最大时能获得最多奖励的排序结果

数据&部分分:

对于 10%的数据,n ≤ 10,q = 1, 每个字符串的长度不超过 50; 
对于 20%的数据,n ≤ 50,q = 1, 每个字符串的长度不超过 50; 
对于 50%的数据,n ≤ 1000,q ≤ 1000, 每个字符串的长度不超过 1000; 
对于 70%的数据,任意字符串不为其他任何一个字符串的前缀; 
对于100%的数据, n ≤ 40 000, q ≤ 100 000, 每个字符串的长度不超过10 000; 
对于 100%的数据,所有字符串的长度和不超过 200000。

bzoj坑爹啊,没有数据范围,还好Codevs上有

思路:

嗯,WJMZBMR远古巨神的神题,肯定不是我等一般人能做出来的
当然,在我有理有据的乱搞之前,我们先要确定这道题考的是啥
多个串,很像AC自动机,但LCP又跟AC自动机联系不起来,
苦苦思索2晚上无果后我的思路到了关键的一点:陈立杰在2012年的《后缀自动机讲稿》上有这么一句话

然后我就确定了:不会有后缀数据结构,毕竟CTSC也不太可能会出后缀数组
好,那么字符串还剩下什么数据结构呢
我们看数据范围的最后一条
答案脱口而出:Trie树!
对,就是Trie树大暴力

整理一下思路:我们明确两个大方向
(1)根据历史的进程,这道题一定是Trie树
(2)Trie树上的LCP,其实就是LCA的深度

好,现在我们开始做题
我们写一个动态Trie动态维护排序信息

别急,先打打暴力,看看有没有什么特殊性质
于是我在数学课上手算了4组数据发现
第一问是tm逗你玩的,W最大的情况是"字典序"
本来想着dp的我抱头痛哭

严谨证明的话...不太会

可能是在Trie树上搞个路径统计?

可以知道的是:一个字符串排列就相当于Trie树上一条从根出发回到根的路径

不知道,反正这一问在Trie树上按字典序dfs一下就好了

我们看第二问
第二问会发现,越往后奖励越多,所以我们考虑操作离线倒序,如果当前任务可以取就取到,然后更改Trie树上的路径(我就是在这yy出了LinkCutTrie的)

于是开始了漫长的手推

草稿纸都用了一张多,最后发现可以弄一个Trie链剖分+树套树

看了看前人的代码长度大概都是这么做的吧

然后在纸上写了很多乱七八糟的东西

...要滚去写作业了,幸运的是找到了曾经的题解

也算是看了一点点吧

毕竟还是个没学上的蒟蒻不可能一下子A掉CTSC的是不是?

放个链接吧

https://wenku.baidu.com/view/d6e7e02b647d27284b73516a.html?from=search

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
const int maxn=40010;
const int maxq=100010;
int n,q,dfn;
int x[maxq],y[maxq];
char SS[maxn];
struct Trie
{Trie *ch[27];int Size,dep,rnk;Trie *prev,*next;Trie *first,*last;Trie *father,*top;Trie(){memset(ch,0,sizeof(ch));Size=0;father=0;prev=next=first=last=0;}Trie *pre(){Trie *now;for(now=this;now->prev;now=now->prev);return now;}Trie *suf() {Trie *now;for(now=this;now->next;now=now->next);return now;}Trie *insert(int val){Trie* &now=ch[val];if (now==0){now=new Trie;now->father=this;Size++;}return now;}int count() {Trie *now=pre();int cnt=0;while(now) {++cnt;now=now->next;}return cnt;}bool find(Trie*o) {Trie *now=pre();while(now) {if(now==o)return true;now=now->next;}return false;}bool canFirst(Trie*c) {if (c==first)return true;if (first != 0 || c->prev != 0)return false;if (c->suf()==last && c->count()!=Size)return false;return true;}bool canLast(Trie*c) {if (c == last)return true;if (last!=0 || c->next!=0)return false;if (c->pre()==first && c->count()!=Size)return false;return true;}bool canNext(Trie*c1,Trie*c2) {if (c1->next==c2)return true;if (c1->next!=0 || c2->prev!=0)return false;if (c1==last || c2==first)return false;if (c1->find(c2))return false;if (c1->pre()==first && c2->suf()==last && c1->count()+c2->count()<Size)return false;return true;}void dfs(int de) {rnk=dfn++;dep=de;if(father==0) top=0; else if(father->Size>1)top=father;else top=father->top;for(int i=0;i<27;i++)if(ch[i]!=0)ch[i]->dfs(dep+1);}
};
int todolis[maxq];
Trie *es[maxn],*ed[maxn],*rt;
Trie *getLCA(Trie *a, Trie *b)
{while("woxihuan_keduoli"){if(a==b)return a;if(a==rt || b==rt)return rt;if( (a->top->dep) < (b->top->dep) )swap(a,b);a=a->top;}
}
void set(Trie *a,Trie *b)
{Trie *l=getLCA(a,b);while(a->top!=l) {Trie*fa=a->top;fa->last=a;a=fa;}while(b->top!=l) {Trie*fa=b->top;fa->first=b;b=fa;}a->next=b,b->prev=a;
}
bool check(Trie *a, Trie *b)
{Trie *l=getLCA(a, b);while(a->top!=l) {Trie*fa=a->top;if(!fa->canLast(a))return false;a=fa;}while(b->top!=l) {Trie*fa=b->top;if(!fa->canFirst(b))return false;b=fa;}if(!l->canNext(a,b))return false;return true;
}
bool cmp(Trie*a, Trie*b){return (a->rnk) < (b->rnk);}
ll ans,cnt;
int main()
{scanf("%d%d",&n,&q);rt=new Trie;for(int i=0;i<n;i++) {scanf("%s",SS);int len=strlen(SS);Trie *temp=rt;for(int j=0;j<len;j++)temp=temp->insert(SS[j]-'a'+1);temp=temp->insert(0);ed[i]=temp;}ll ans=0;rt->dfs(0);for(int i=0;i<q;i++) scanf("%d%d",&x[i],&y[i]),--x[i],--y[i];for(int i=q-1;i>=0;i--) if(check(ed[x[i]],ed[y[i]])) {set(ed[x[i]],ed[y[i]]);++cnt;todolis[i]=1;}for(int i=0;i<n;i++)es[i]=ed[i];sort(es,es+n,cmp);ll tmp;for(int i=0;i<n-1;i++){tmp=getLCA(es[i],es[i+1])->dep;ans+=tmp*tmp;}printf("%lld\n%lld\n",ans,cnt);for(int i=0;i<q;i++)if(todolis[i])printf("%d ",i+1);return 0;
}

View Code

OI加油 期末加油

转载于:https://www.cnblogs.com/Kong-Ruo/p/8270838.html

bzoj2309 CTSC2011 字符串重排相关推荐

  1. java 判断字符串重排后是否等于另一个字符串,包括空格符

    大家好,很高兴能和你认识,这是本人第一篇博文,本着提升自我而开始的博客之旅 下面只要写的是java字符串重排后是否相等的. public static void main(String [] args ...

  2. 判断字符串重排后是否相同(区分大小写)

    /*** 题目: * 给定两个字符串,请编写程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串.* 这里规定大小写为不同字符,且考虑字符串重点空格.* 给定一个string stringA ...

  3. python random seed,python - 字符串重排:固定seed()下利用random.shuffle()简化代码

    目录: 目的:理解random.seed(),通过代码探究并验证其功能. 背景:random()是伪随机,实际上由确定公式根据初始值seed计算得出. 当seed固定时,对特定数据的处理会产生相同的结 ...

  4. 【145】字符串重排(输出字符串的所有不同的排列数)

    ♣题目部分(原文见公众号:python宝) 题目描述 给定一个只包含大写英文字母的字符串S,要求你给出对S重新排列的所有不相同的排列数(包括自己本身). 如:S为ABA,则不同的排列有ABA.AAB. ...

  5. 【学习笔记】树上启发式合并

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 树上启发式合并 模板 复杂度分析 例题 **Problem A. Arpa's letter-m ...

  6. (树上启发式合并)CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Weblink https://www.luogu.com.cn/problem/CF741D Pro ...

  7. 华师大 OJ 3055

    题目描述:点击打开链接 值得一提的是,对这里的题目描述要理解准确. #include <stdio.h> #include <stdlib.h> #include <st ...

  8. 北京信息科技大学第十三届程序设计竞赛暨ACM选拔赛题解

    北京信息科技大学第十三届程序设计竞赛暨ACM选拔赛题解 A lzh的蹦床 B 所谓过河 C 旅行家问题1 D 旅行家问题2 E 小菲和Fib数列 F 好玩的音乐游戏 G ranko的手表 H 字母收集 ...

  9. 2019届华为实习生招聘

    4.10   在线笔试 华为的笔试题跟其他公司的有点不太一样,没有选择题,三道编程题,共600分.第一题100分,我收到的是字符串重排(详见我的博客):第二题200分,是跳跃游戏,lintcode T ...

最新文章

  1. CodeSmith实用技巧(十五):使用快捷键
  2. MySQL主从失败 错误Got fatal error 1236解决方法
  3. Dockerfiles基础语法
  4. 关于 redis.properties配置文件及rule
  5. CentOS7,linux下nginx的安装过程——2.配置user,路径,openssl,make install,关闭防火墙,测试——源码
  6. Java对接SAP平台接口
  7. 智能家居要走平民化路线
  8. php zip下载损坏,php – 从zip中提取时损坏图像
  9. get mysql options_mysql命令的选项options
  10. malware analysis、Sandbox Principles、Design Implementation
  11. 推荐一款专为新手用的Python开发工具
  12. 32位电脑适合装W ndows10,32位再见?微软将停止支持32位Win10系统
  13. 老板喜欢的高绩效哪里来?
  14. 从乐清女孩发出救命信息后殒命想到,微信滴滴应增加SOS求救功能
  15. Android长截图(五) - 遇到的坑
  16. 计算机毕业设计springboot睎晴贸易公司安保保洁管理平台
  17. 电脑大写,电脑大写键盘怎么打开
  18. oracle注册表重建,一次Windows 注册表中注册表项目丢失导致的Oracle 数据库启动问题。...
  19. 华雨欢:多日震荡趋势明显,本周即将结束要开启每周大行情了
  20. 【计算机组成原理】计算机硬件的基础组成、认识各个硬件部件

热门文章

  1. 微盟餐饮SaaS蜕变时刻:战略投资奥琦玮,领军之势已成
  2. centos6.5下载卸载mysql_CentOS 6.5系统卸载MySQL并安装MariaDB的方法
  3. 关于共享单车定位不准问题
  4. 传说中的oracle的java证书这个样子!
  5. 阿里云服务器配置及把java项目部署到服务器
  6. 利用python 解对称正定矩阵方程组的平方根法
  7. 激励团队最实用的七种方法
  8. 数字水印处理的小小心得!!!
  9. 面对企业校招,你的背景够格吗?(限学生阅读)
  10. 《数据结构与算法》——线性表顺序存储结构的插入与删除