1. 所有公共子序列问题
(allcs.pas/c/cpp)
★问题描述:
一个给定序列的子序列是在该序列中删去若干元素后得到的序列。确切地说,若给定序
列X= x 1 x 2 ... x m ,则另一序列Z= z 1 z 2 ... z k 是X的子序列是指存在一个严格递增下标序列
i 1 , i 2 ,..., i k 使得对于所有j=1,2,...,k有 z j  x ij 。例如,序列Z=GACT是序列X= GCTACT的子
序列,相应的递增下标序列为1,4,5,6。给定2个序列X和Y,当另一序列Z既是X的子序列又是
Y的子序列时,称Z是序列X和Y的公共子序列。例如,若X= GCTACT,Y= GATCCT,序列
TT是X和Y的一个公共子序列,序列GACT也是X和Y的一个公共子序列。注意对于任何给定
的序列X和Y,空序列总是它们的一个公共子序列。
所有公共子序列问题是要求对于给定的2个序列X= x 1 x 2 ... x m 和Y= y 1 y 2 ... y n ,找出X
和Y的所有不同的公共子序列。
★编程任务:
对于给定的2个序列X= x 1 x 2 ... x m 和Y= y 1 y 2 ... y n ,根据输入数据的要求,找出它们所
有不同的公共子序列,或计算出它们有多少个不同的公共子序列。
★数据输入:
输入文件名为allcs.in。
文件的第一行有2个正整数m和n, (1<=m,n<=3010),分别表示2个输入序列X和Y的长度。
接下来的2行分别给出输入序列X= x 1 x 2 ... x m 和Y= y 1 y 2 ... y n 。其中序列中每个元素均为26
个英文大小写字母。文件的最后一行给出一个非负整数k。k的值为1时,表示计算结果要输
出X和Y的所有不同的公共子序列,以及X和Y有多少个不同的公共子序列。k的值为0时,表
示计算结果只要输出X和Y有多少个不同的公共子序列。
★结果输出:
输出文件名为allcs.out。
将计算出的X和Y的所有不同的公共子序列,或X和Y有多少个不同的公共子序列输出到
文件中。当k=1时,先输出X和Y的所有不同的公共子序列,每行输出1个公共子序列,按字
典序从小到大输出。最后输出不同的公共子序列的个数。当k=0时,只要输出不同的公共子
序列的个数。

输入示例1
6 6
GCTACT
GATCCT
1

输出示例1
26
A
AC
ACT
AT
C
CC
CCT
CT
G
GA
GAC
GACT
GAT
GC
GCC
GCCT
GCT
GT
GTC
GTCT
GTT
T
TC
TCT
TT
26

输入示例2
6 6
GCTACT
GATCCT
0

输出示例2
26

根连向每个字母第一次出现的位置,每个位置的儿子分别连向它之后每个字母第一次出现的位置.这貌似就是传说中的序列自动机.

在两个序列自动机同时dfs.需要输出序列则直接dfs并输出即可.

不需要输出序列时,记忆化搜索.但是由于答案很大,需要高精.

std又WA又T又RE,我也没有什么办法.

70分代码.

 //Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int N=;
typedef long long LL;
typedef double db;
using namespace std;
char a[N],b[N],prt[N];
int n,m,K,ch1[N][],ch2[N][],ls[]; template<typename T> void read(T &x) {
char ch=getchar(); x=; T f=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} void make_it(char s[],int n,int ch[][]) {
memset(ls,,sizeof(ls));
For(i,,n) {
int c=(s[i]>='a'&&s[i]<='z')?s[i]-'a':+s[i]-'A';
if(!ls[c]) ch[][c]=i;
ls[c]=i;
}
memset(ls,,sizeof(ls));
Rep(i,n,) {
int c=(s[i]>='a'&&s[i]<='z')?s[i]-'a':+s[i]-'A';
For(j,,) ch[i][j]=ls[j];
ls[c]=i;
}
} int dp[N][N],tot;
struct G {
int len;
LL d[];
}; const LL bs=1e17;
G operator +(const G&A,const G&B) {
G rs;
For(i,,) rs.d[i]=;
rs.len=max(A.len,B.len)+;
LL pr=;
For(i,,rs.len) {
rs.d[i]=A.d[i]+B.d[i]+pr;
if(rs.d[i]>=bs) pr=,rs.d[i]-=bs;
else pr=;
}
while(rs.d[rs.len]==) rs.len--;
return rs;
} G ans,g[]; G dfs(int x,int y) {
if(dp[x][y]!=-) return g[dp[x][y]];
dp[x][y]=++tot;
G rs; rs.len=;
For(i,,) rs.d[i]=; rs.d[]=;
For(i,,) if(ch1[x][i]&&ch2[y][i]) {
rs=rs+dfs(ch1[x][i],ch2[y][i]);
}
g[dp[x][y]]=rs;
return rs;
} void PT(G a) {
printf("%lld",a.d[a.len]);
Rep(i,a.len-,) {
if(a.d[i]==) printf("");
else {
LL tp=a.d[i];
while(tp*<bs) { printf(""); tp*=; }
printf("%lld",a.d[i]);
}
} printf("\n");
} int anstot;
void print(int x,int y,int pos) {
prt[pos]=a[x];
prt[pos+]=;
puts(prt); anstot++;
For(i,,) if(ch1[x][i]&&ch2[y][i])
print(ch1[x][i],ch2[y][i],pos+);
} #define DEBUG
int main() {
#ifdef DEBUG
freopen("allcs.in","r",stdin);
freopen("allcs.out","w",stdout);
#endif
read(n); read(m);
scanf("%s",a+);
make_it(a,n,ch1);
scanf("%s",b+);
make_it(b,m,ch2);
read(K);
memset(dp,-,sizeof(dp));
if(!K) {
ans.len=;
For(i,,) ans.d[i]=; ans.d[]=;
For(i,,)
if(ch1[][i]&&ch2[][i])
ans=ans+dfs(ch1[][i],ch2[][i]);
PT(ans);
}
if(K) {
puts("");
For(i,,)
if(ch1[][i]&&ch2[][i])
print(ch1[][i],ch2[][i],);
printf("%d\n",anstot+);
}
return ;
}

2. 建筑师
(building.pas/c/cpp)
★问题描述:
小Z是一个很有名的建筑师,有一天他接到了一个很奇怪的任务:在数轴上建n个建筑,
每个建筑的高度是1到n之间的一个整数。小Z有很严重的强迫症,他不喜欢有两个建筑的高
度相同。另外小Z觉得如果从最左边(所有建筑都在右边)看能看到A个建筑,从最右边(所
有建筑都在左边)看能看到B个建筑,这样的建筑群有着独特的美感。现在,小Z想知道满足
上述所有条件的建筑方案有多少种?
如果建筑i的左(右)边没有任何建造比它高,则建筑i可以从左(右)边看到。两种方案不
同,当且仅当存在某个建筑在两种方案下的高度不同。
★数据输入:
输入文件名为building.in。
第一行一个整数 T,代表 T 组数据。
接下来T行,每行三个整数n,A,B。
★结果输出:
输出文件名为building.out。
9
对于每组数据输出一行答案 mod ( 10 ^9+ 7 ) 。

输入示例
2
3 2 2
3 1 2

输出示例
2
1

★数据范围:
10% : 1 <= n <= 10
20% : 1 <= n <= 100
40% : 1 <= n <= 50000,1 <= T <= 5
100% :1 <= n <= 50000,1 <= A, B <= 100,1 <= T <= 200000。

题解在这里

 //Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
const int N=5e4+;
const int mod=1e9+;
typedef long long LL;
using namespace std;
LL dp[N][],C[][];
int T,n,a,b; template<typename T> void read(T &x) {
char ch=getchar(); T f=; x=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} #define DEBUG
int main() {
#ifdef DEBUG
freopen("building.in","r",stdin);
freopen("building.out","w",stdout);
#endif
dp[][]=;
for(int i=;i<=;i++)
for(int k=;k<=min(,i);k++)
dp[i][k]=(dp[i-][k]*(i-)%mod+dp[i-][k-])%mod;
for(int i=;i<=;i++) C[i][]=;
for(int i=;i<=;i++)
for(int j=;j<=i;j++)
C[i][j]=(C[i-][j]+C[i-][j-])%mod;
read(T);
while(T--) {
read(n); read(a); read(b);
LL ans=dp[n-][a+b-];
ans=(ans*C[a+b-][a-])%mod;
printf("%lld\n",ans);
}
return ;
}
/*
3 2 2
2 1
*/

3. 神秘数
(mystic.pas/c/cpp)
★问题描述:
一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数。例如
S={1,1,1,4,13},
1 = 1
2 = 1+1
3 = 1+1+1
4 = 4
5 = 4+1
6 = 4+1+1
7 = 4+1+1+1
8无法表示为集合S的子集的和,故集合S的神秘数为8。
现给定n个正整数a[1]..a[n],m个询问,每次询问给定一个区间[l,r](l<=r),求由
a[l],a[l+1],...,a[r]所构成的可重复数字集合的神秘数。
★编程任务:
求出每个查询的结果。
★数据输入:
输入文件名为mystic.in。
第一行一个整数n,表示数字个数。
第二行n个整数,从1编号。
第三行一个整数m,表示询问个数。
以下m行,每行一对整数l,r,表示一个询问。
★结果输出:
输出文件名为mystic.out。
对于每个询问,输出一行对应的答案。

输入示例
5
1 2 4 9 10
5
1 1
1 2
1 3
1 4
1 5

输出示例
2
4
8
8
8

★数据范围:
对于 10%的数据点,n,m <= 10
对于 30%的数据点,n,m <= 1000
对于 60%的数据点,n,m <= 50000
对于 100%的数据点,n,m <= 100000,∑a[i] <= 10

十分奥妙的一道题.

求一段区间的神秘数,先把区间内的数从小到大排序.

依次加入每个数x,若当前神秘数为ans

若x>ans+1,神秘数仍为ans

否则神秘数变为ans+x

排序后,找到第一个大于它前面所有数的和+1的数,它前面所有数的和+1即为神秘数.

那么求区间l,r的神秘数,先将当前神秘数ans设为1,查询区间内小于等于ans的数的和sum,若sum>ans,则ans=sum+1

 //Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#include<set>
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int N=;
typedef long long LL;
typedef double db;
using namespace std;
int n,m,a[N],sz; template<typename T> void read(T &x) {
char ch=getchar(); x=; T f=;
while(ch!='-'&&(ch<''||ch>'')) ch=getchar();
if(ch=='-') f=-,ch=getchar();
for(;ch>=''&&ch<='';ch=getchar()) x=x*+ch-''; x*=f;
} int tot,rt[N],sg[N*],ls[N*],rs[N*];
#define lc ls[x]
#define rc rs[x]
#define mid ((l+r)>>1)
void update(int &x,int l,int r,int pos,int last) {
x=++tot;
sg[x]=sg[last]+pos;
lc=ls[last];
rc=rs[last];
if(l==r) return;
if(pos<=mid) update(lc,l,mid,pos,ls[last]);
else update(rc,mid+,r,pos,rs[last]);
} int qry(int x,int l,int r,int ql,int qr) {
if(!x) return ;
if(l>=ql&&r<=qr) return sg[x];
if(qr<=mid) return qry(lc,l,mid,ql,qr);
if(ql>mid) return qry(rc,mid+,r,ql,qr);
return qry(lc,l,mid,ql,qr)+qry(rc,mid+,r,ql,qr);
} #define DEBUG
int main() {
#ifdef DEBUG
freopen("mysti.in","r",stdin);
freopen("mysti.out","w",stdout);
#endif
read(n);
For(i,,n) { read(a[i]); sz=max(sz,a[i]); }
For(i,,n) update(rt[i],,sz,a[i],rt[i-]);
read(m);
For(i,,m) {
int l,r;
read(l); read(r);
int ans=;
for(;;) {
int tp=qry(rt[r],,sz,,ans)-qry(rt[l-],,sz,,ans);
if(tp<ans) break;
ans=tp+;
}
printf("%d\n",ans);
}
return ;
}

说不出是什么心情,只能说.道不同不相为谋吧.

(UPD:似乎不知不觉间通往另一个end了)

【自家测试】2017-12-16 FJOI2016 d1的更多相关文章

  1. 12.16 Daily Scrum

      Today's Task Tomorrow's Task 丁辛 实现和菜谱相关的餐厅列表. 实现和菜谱相关的餐厅列表.             邓亚梅             美化搜索框UI. 美 ...

  2. 2017.12.21-JQuery

    作业:密码加强验证 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> & ...

  3. 2017.12.25 Mybatis物理分页插件PageHelper的使用(二)

    参考来自: 官方文档的说明:https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md 上篇博客 ...

  4. Proteus中的 PIC10/12/16 MCUs编译器无法下载的问题

    当你打开网站时,点击该软件下载会发现如下页面: google一下会出现这个界面,大意是这个版本的编译器太老了,已经被某些更加高级的编译器给取代了(qaq心痛) 然后我就开始FQ到处google,Sou ...

  5. mysql查询练习题-2016.12.16

    >>>>>>>>>> 练习时间:2016.12.16 编辑时间:2016-12-20-->22:12:08 题: 涉及:多表查询.ex ...

  6. KALI LINUX WEB 渗透测试视频教程—第16课 BEEF基本使用

    Kali Linux Web 渗透测试视频教程—第16课  BeEF基本使用 文/玄魂 目录 Kali Linux Web 渗透测试视频教程—第16课  BeEF基本使用............... ...

  7. Gitlab一键端的安装汉化及问题解决(2017/12/14目前版本为10.2.4)

    Gitlab的安装汉化及问题解决 一.前言 Gitlab需要安装的包太TM多了,源码安装能愁死个人,一直出错,后来发现几行命令就装的真是遇到的新大陆一样... ... 装完之后感觉太简单,加了汉化补丁 ...

  8. 2017.9.16~17,热烈庆祝共创力罗老师《敏捷MINI体验式实战培训》在某大型企业成功举办!

    2017.9.16~17日,深圳市共创力企业管理咨询有限公司为某上市企业提供了为期两天的内训服务.该次内训的主题为<敏捷MINI体验式实践培训>,为期两天.此次培训由共创力资深讲师Geor ...

  9. 【2017.12.12】deepin安装U盘制作,支持 BIOS+UEFI,deepin_Recovery+Win PE

    U盘要求为 FAT32,MBR分区表 如果需要放 4GB 大文件,可以分两个分区,第一分区FAT32格式,放启动相关文件,第二个分区用 NTFS 格式,放其它资料. 最新 Win10 支持显示 U盘 ...

随机推荐

  1. Day15:Python 【模块】及__name__:

    什么是模块: 在Python中,随着这代码的撰写,代码越来越长,所以产生了,模块这个概念,模块是什么?模块就是一个.py文件,在撰写代码时,我们把不同的功能的代码封装到一个.py文件里,用得时候导入 ...

  2. Adobe Fireworks CS6 win64的安装

    网页三大剑客之一    FW的安装 本人也是找了半天才找到的. (没有视频)这里先感谢原帖给我的链接https://blog.csdn.net/qq_38053395/article/details/ ...

  3. springDataJpa的官方API

    一 .  Core concepts(核心概念) 1.springdata中的中心接口是——Repository.这个接口没有什么重要的功能(原句称没什么惊喜的一个接口).主要的作用就是标记和管理.其 ...

  4. codis 使用

    1:Jedis与Redisson对比 2.1. 概况对比 Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持:Redisson实现了分布式和可扩展的Java数据 ...

  5. elast数据存放

    这几天一直在索引数据,突然发现服务器状态变红色了,去官网看了下 集群状态如果是红色的话表示有数据已经丢失了!这下头大了才索引了7G数据,后面还有10多个G, 我在liunx下看了下磁盘空间 发现运行e ...

  6. sql(7)

    EXCEPT是指在第一个集合中存在,但是不存在于第二个集合中的数据. EXCEPT 子句/运算符用于将两个 SELECT 语句结合在一起,并返回第一个 SELECT 语句的结果中那些不存在于第二个 S ...

  7. OrCAD(2) -- 编辑原理图库时的复制与粘贴

    大家都知道,OrCAD元器件的管脚编辑是基于Excel的,但是在编辑原理图库的管脚的时候,大家应该都有体会'ctrl+c' 和 'ctrl+v' 的命令是不能用的. 这是因为该两个命令在OrCAD中都 ...

  8. 【JZOJ6342】Tiny Counting

    description analysis 首先不管\(a,b,c,d\)重复的情况方案数是正逆序对之积 如果考虑\(a,b,c,d\)有重复,只有四种情况,下面括号括起来表示该位置重复 比如\(\{a ...

  9. flask中abort()函数的使用

    一.介绍 #从flask中导入abort from flask import abort abort()函数的作用 可以让开发者在检测到web访问错误时,立即将错误信息返回回去,返回的错误码必须是已知 ...

  10. react diff 极简版

    为什么react这么快呢 ? 因为react用了虚拟DOM: 但是每次虚拟DOM转真实DOM不也是很浪费性能吗 ? nice,所以关键点在Diff算法这里,去对比新旧DOM树,而后通过补丁去更新到真实 ...