@ivorysi
2018-01-02T08:28:32.000000Z
字数 30858
阅读 852
笔记
Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = "" (the empty string) and a^(n+1) = a*(a^n).
Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.
For each s you should print the largest n such that s = a^n for some string a.
abcd
aaaa
ababab
.
1
4
3
用扩展kmp做
求出next数组是原串i位置和第一个位置的最长公共前缀,从大到小枚举n(约数只有的级别)
然后暴力判断即可
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <cmath>
#define siji(i,x,y) for(int i=(x);i<=(y);++i)
#define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
#define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
#define MAXN 1000005
#define mod 1000000007
//#define ivorysi
using namespace std;
typedef long long ll;
ll read() {
ll res=0,neg=1;
char c=getchar();
while(c<'0' || c>'9') {
if(c=='-') neg=-1;
c=getchar();
}
while(c>='0' && c<='9') {
res=res*10+c-'0';
c=getchar();
}
return res*neg;
}
char s[MAXN];
int next[MAXN],len;
void solve() {
len=strlen(s+1);
memset(next,0,sizeof(next));
next[1]=len;
int pos=0,maxright=0;
siji(i,2,len) {
int z=next[i-pos+1];
if(i+z>maxright) {
z=max(0,maxright-i+1);
while(s[i+z]==s[z+1]) ++z;
}
next[i]=z;
if(i+z-1>maxright) {
maxright=i+z-1;
pos=i;
}
}
gongzi(i,len,2) {
if(len%i==0) {
int l=len/i;
bool flag=1;
xiaosiji(j,0,i) {
if(next[j*l+1]>=l) continue;
else {flag=0;break;}
}
if(flag) {
printf("%d\n",i);
return;
}
}
}
puts("1");
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
while(1) {
scanf("%s",s+1);
if(s[1]=='.') break;
solve();
}
}
One day Om Nom found a thread with n beads of different colors. He decided to cut the first several beads from this thread to make a bead necklace and present it to his girlfriend Om Nelly.
Om Nom knows that his girlfriend loves beautiful patterns. That's why he wants the beads on the necklace to form a regular pattern. A sequence of beads S is regular if it can be represented as S = A + B + A + B + A + ... + A + B + A, where A and B are some bead sequences, " + " is the concatenation of sequences, there are exactly 2k + 1 summands in this sum, among which there are k + 1 "A" summands and k "B" summands that follow in alternating order. Om Nelly knows that her friend is an eager mathematician, so she doesn't mind if A or B is an empty sequence.
Help Om Nom determine in which ways he can cut off the first several beads from the found thread (at least one; probably, all) so that they form a regular pattern. When Om Nom cuts off the beads, he doesn't change their order.
The first line contains two integers n, k (1 ≤ n, k ≤ 1 000 000) — the number of beads on the thread that Om Nom found and number k from the definition of the regular sequence above.
The second line contains the sequence of n lowercase Latin letters that represent the colors of the beads. Each color corresponds to a single letter.
Print a string consisting of n zeroes and ones. Position i (1 ≤ i ≤ n) must contain either number one if the first i beads on the thread form a regular sequence, or a zero otherwise.
Examples
7 2
bcabcab
0000011
21 2
ababaababaababaababaa
000110000111111000011
我们可以求出每个点和起点的最长公共前缀有多长,然后我们发现,每一个串必定是一些相等的区块A+B组成的,最后一个A是这个区块的一个前缀
然后我们枚举每一个A+B的长度l,k*l+1与第一位的最长公共前缀与l取个min,表示A能取的大小,这一段区间都是可以被切下来的
枚举长度和判断花费n/k*k=n的贡献,然后统计这些区间可以用差分,最后一次性更新,如果这个下标被覆盖过,那么这个下标就是可以从这里切断的
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#define siji(i,x,y) for(int i=(x);i<=(y);++i)
#define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
#define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
#define MAXN 1000005
//#define ivorysi
using namespace std;
typedef long long ll;
int readint() {
int res=0;
char c=getchar();
while(c<'0' || c>'9') {
c=getchar();
}
while(c>='0' && c<='9') {
res=res*10+c-'0';
c=getchar();
}
return res;
}
void out(ll x) {
if(x>=10) {
out(x/10);
}
putchar('0'+x%10);
}
int n,k;
char s[MAXN];
int next[MAXN];
int ans[MAXN*5];
void solve() {
n=readint();k=readint();
scanf("%s",s+1);
next[1]=n;
int pos=0,maxright=0;
siji(i,2,n) {
int j=next[i-pos+1];
if(i+j>=maxright) {
j=max(0,maxright-i+1);
while(s[i+j]==s[j+1]) {
++j;
}
}
if(i+j-1>maxright) {
pos=i;
maxright=i+j-1;
}
next[i]=j;
}
siji(i,1,n) {
if(i<=n/k) {
bool flag=1;
int t=1;
siji(j,2,k) {
t+=i;
if(next[t]<i) {
flag=0;
break;
}
}
t+=i;
if(flag) {
int st=t-1,ed=t+min(next[t],i)-1;
ans[st]++;
ans[ed+1]--;
}
}
else {
break;
}
}
siji(i,1,n) {
ans[i]+=ans[i-1];
}
siji(i,1,n) {
if(ans[i]!=0) {
putchar('1');
}
else {
putchar('0');
}
}
putchar('\n');
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
solve();
}
Doubleville, a small town in Texas, was attacked by the aliens. They have abducted some of the residents and taken them to the a spaceship orbiting around earth. After some (quite unpleasant) human experiments, the aliens cloned the victims, and released multiple copies of them back in Doubleville. So now it might happen that there are 6 identical person named Hugh F. Bumblebee: the original person and its 5 copies. The Federal Bureau of Unauthorized Cloning (FBUC) charged you with the task of determining how many copies were made from each person. To help you in your task, FBUC have collected a DNA sample from each person. All copies of the same person have the same DNA sequence, and different people have different sequences (we know that there are no identical twins in the town, this is not an issue).
The input contains several blocks of test cases. Each case begins with a line containing two integers: the number 1 ≤ n ≤ 20000 people, and the length 1 ≤ m ≤ 20 of the DNA sequences. The next n lines contain the DNA sequences: each line contains a sequence of m characters, where each character is either
A',
C',G' or
T'.
The input is terminated by a block with n = m = 0 .
For each test case, you have to output n lines, each line containing a single integer. The first line contains the number of different people that were not copied. The second line contains the number of people that were copied only once (i.e., there are two identical copies for each such person.) The third line contains the number of people that are present in three identical copies, and so on: the i -th line contains the number of persons that are present in i identical copies. For example, if there are 11 samples, one of them is from John Smith, and all the others are from copies of Joe Foobar, then you have to print
1' in the first andthe tenth lines, and
0' in all the other lines.
9 6
AAAAAA
ACACAC
GTTTTG
ACACAC
GTTTTG
ACACAC
ACACAC
TCCCCC
TCCCCC
0 0
1
2
0
1
0
0
0
0
0
Huge input file, 'scanf' recommended to avoid TLE.
建一个trie树然后深搜
找到对应深度的地方然后,然后累加到ans上
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <cmath>
#define siji(i,x,y) for(int i=(x);i<=(y);++i)
#define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
#define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
#define MAXN 400005
#define mod 1000000007
//#define ivorysi
using namespace std;
typedef long long ll;
ll read() {
ll res=0,neg=1;
char c=getchar();
while(c<'0' || c>'9') {
if(c=='-') neg=-1;
c=getchar();
}
while(c>='0' && c<='9') {
res=res*10+c-'0';
c=getchar();
}
return res*neg;
}
struct node {
int to,next;
char val;
}edge[MAXN];
char s[MAXN];
int n,m;
int head[MAXN],sumedge,nodecnt=1,cnt[MAXN],ans[MAXN];
void add(int u,int v,char c) {
edge[++sumedge].to=v;
edge[sumedge].next=head[u];
edge[sumedge].val=c;
head[u]=sumedge;
}
void ins() {
int p=1;
siji(k,1,m) {
bool flag=0;
for(int i=head[p];i;i=edge[i].next) {
int v=edge[i].to;
if(edge[i].val==s[k]) {
p=v;
flag=1;
break;
}
}
if(!flag) {
add(p,++nodecnt,s[k]);
p=nodecnt;
}
}
++cnt[p];
}
void dfs(int u,int dep) {
if(dep==m) {
ans[cnt[u]]++;
}
for(int i=head[u];i;i=edge[i].next) {
int v=edge[i].to;
dfs(v,dep+1);
}
}
void solve() {
sumedge=0;
nodecnt=1;
memset(head,0,sizeof(head));
memset(ans,0,sizeof(ans));
memset(cnt,0,sizeof(cnt));
siji(i,1,n) {
scanf("%s",s+1);
ins();
}
dfs(1,0);
siji(i,1,n) {
printf("%d\n",ans[i]);
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
while(1) {
n=read();m=read();
if(n==0 && m==0) break;
solve();
}
}
A word is a string of lowercases. A word pattern is a string of lowercases, '?'s and ''s. In a pattern, a '?' matches any single lowercase, and a '' matches none or more lowercases.
There are many word patterns and some words in your hand. For each word, your task is to tell which patterns match it.
The first line of input contains two integers N (0 < N <= 100000) and M (0 < M <=100), representing the number of word patterns and the number of words. Each of the following N lines contains a word pattern, assuming all the patterns are numbered from 0 to N-1. After those, each of the last M lines contains a word.
You can assume that the length of patterns will not exceed 6, and the length of words will not exceed 20.
For each word, print a line contains the numbers of matched patterns by increasing order. Each number is followed by a single blank. If there is no pattern that can match the word, print "Not match".
5 4
t*
?h*s
??e*
*s
?*e
this
the
an
is
0 1 3
0 2 4
Not match
3
好像大多数人都是拿模糊串做的匹配……而我是拿要询问的那些串来建一棵trie树,然后跑上面的模式串
为了剪枝开了一个记忆化搜索,貌似因为开得有点大每次清空的时候导致T,然后把数组改成了规范的样子
有一个地方错了
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#define siji(i,x,y) for(int i=(x);i<=(y);++i)
#define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
#define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
#define MAXN 2005
#define mod 1000000007
//#define ivorysi
using namespace std;
typedef long long ll;
ll read() {
ll res=0,neg=1;
char c=getchar();
while(c<'0' || c>'9') {
if(c=='-') neg=-1;
c=getchar();
}
while(c>='0' && c<='9') {
res=res*10+c-'0';
c=getchar();
}
return res*neg;
}
struct node {
int to,next;
char val;
}edge[MAXN*2];
int head[MAXN],sumedge,pos[MAXN],nodecnt=1,fa[MAXN];
vector<int> ans[105];
int n,m;
char str[100005][10],s[25];
int getfa(int x) {
return x==fa[x]? x:fa[x]=getfa(fa[x]);
}
void add(int u,int v,char c) {
edge[++sumedge].to=v;
edge[sumedge].val=c;
edge[sumedge].next=head[u];
head[u]=sumedge;
}
void ins(int x) {
int l=strlen(s+1);
int p=1;
siji(k,1,l) {
bool flag=0;
for(int i=head[p];i;i=edge[i].next) {
int v=edge[i].to;
if(edge[i].val==s[k]) {
p=v;
flag=1;
break;
}
}
if(!flag) {
add(p,++nodecnt,s[k]);
p=nodecnt;
}
}
if(pos[p]!=0) fa[getfa(x)]=getfa(pos[p]);
else pos[p]=x;
}
int now,len;
bool used[MAXN][15];
void dfs(int u,int p) {
if(used[u][p]) {
return;
}
used[u][p]=1;
if(pos[u]!=0 && p==len) {
ans[pos[u]].push_back(now);
}
if(p!=len && s[p+1]=='*') dfs(u,p+1);
for(int i=head[u];i;i=edge[i].next) {
int v=edge[i].to;
if(p!=len && (edge[i].val==s[p+1] || s[p+1]=='?')) {
dfs(v,p+1);
}
if(p!=0 && s[p]=='*') {//这里不能写else因为这种情况一定要搜索一下
dfs(v,p);
}
}
}
void solve() {
n=read();m=read();
siji(i,1,n) {
scanf("%s",str[i]+1);
}
siji(i,1,m) {
fa[i]=i;
scanf("%s",s+1);
ins(i);
}
siji(i,1,n) {
now=i;
strcpy(s+1,str[i]+1);
len=strlen(str[i]+1);
/*int cnt=0;
bool flag=0;
int l=strlen(str[i]+1);
siji(j,1,l) {
if(str[i][j]!='?' && str[i][j]!='*') {
siji(k,1,cnt) {
s[++len]='?';
}
if(flag) s[++len]='*';
s[++len]=str[i][j];
flag=0;cnt=0;
}
else if(str[i][j]=='?') {
++cnt;
}
else if(str[i][j]=='*') {
flag=1;
}
}
siji(i,1,cnt) s[++len]='?';
if(flag) s[++len]='*';*/
memset(used,0,sizeof(used));
dfs(1,0);
}
siji(i,1,m) {
int t=getfa(i);
int s=ans[t].size();
if(s==0) {
puts("Not match");
}
else {
xiaosiji(j,0,s) {
printf("%d ",ans[t][j]-1);
}
puts("");
}
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
solve();
}
After observing the results of Spy Syndrome, Yash realised the errors of his ways. He now believes that a super spy such as Siddhant can't use a cipher as basic and ancient as Caesar cipher. After many weeks of observation of Siddhant’s sentences, Yash determined a new cipher technique.
For a given sentence, the cipher is processed as:
Convert all letters of the sentence to lowercase.
Reverse each of the words of the sentence individually.
Remove all the spaces in the sentence.
For example, when this cipher is applied to the sentenceKira is childish and he hates losing
the resulting string is
ariksihsidlihcdnaehsetahgnisol
Now Yash is given some ciphered string and a list of words. Help him to find out any original sentence composed using only words from the list. Note, that any of the given words could be used in the sentence multiple times.
The first line of the input contains a single integer n (1 ≤ n ≤ 10 000) — the length of the ciphered text. The second line consists of n lowercase English letters — the ciphered text t.
The third line contains a single integer m (1 ≤ m ≤ 100 000) — the number of words which will be considered while deciphering the text. Each of the next m lines contains a non-empty word wi (|wi| ≤ 1 000) consisting of uppercase and lowercase English letters only. It's guaranteed that the total length of all words doesn't exceed 1 000 000.
Print one line — the original sentence. It is guaranteed that at least one solution exists. If there are multiple solutions, you may output any of those.
30
ariksihsidlihcdnaehsetahgnisol
10
Kira
hates
is
he
losing
death
childish
L
and
Note
Kira is childish and he hates losing
12
iherehtolleh
5
HI
Ho
there
HeLLo
hello
HI there HeLLo
In sample case 2 there may be multiple accepted outputs, "HI there HeLLo" and "HI there hello" you may output any of them.
把每个字符串取反存字典树,然后dp[n]表示能否匹配到n,同时记录一下用的是第几个串还有从哪个位置匹配过来的
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <cmath>
#define siji(i,x,y) for(int i=(x);i<=(y);++i)
#define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
#define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
#define MAXN 10005
#define MAXM 100005
#define mod 1000000007
//#define ivorysi
using namespace std;
typedef long long ll;
ll read() {
ll res=0,neg=1;
char c=getchar();
while(c<'0' || c>'9') {
if(c=='-') neg=-1;
c=getchar();
}
while(c>='0' && c<='9') {
res=res*10+c-'0';
c=getchar();
}
return res*neg;
}
struct node {
int to,next;
char val;
}edge[1000005];
int head[1000005],sumedge,nodecnt=1;
void add(int u,int v,char c) {
edge[++sumedge].to=v;
edge[sumedge].next=head[u];
edge[sumedge].val=c;
head[u]=sumedge;
}
int n,m;
int pos[MAXM],len[MAXM],isend[1000005];
int id[MAXN],from[MAXN],ans[MAXN],tot;
bool dp[MAXN];
char str[MAXN];
char s[1000005];
void ins(int x) {
int p=1;
gongzi(i,len[x],1) {
char t=s[pos[x]+i-1];
if(t>='A' && t<='Z') t='a'+t-'A';
bool flag=0;
for(int l=head[p];l;l=edge[l].next) {
int z=edge[l].to;
if(edge[l].val==t) {
p=z;
flag=1;
break;
}
}
if(!flag) {
add(p,++nodecnt,t);
p=nodecnt;
}
}
if(!isend[p]) {
isend[p]=x;
}
}
int find(int st,int ed) {
int p=1;
siji(i,st,ed) {
bool flag=0;
for(int l=head[p];l;l=edge[l].next) {
int z=edge[l].to;
if(edge[l].val==str[i]) {
p=z;
flag=1;
break;
}
}
if(!flag) return -1;
}
if(!isend[p]) return -1;
else return isend[p];
}
void solve() {
n=read();
scanf("%s",str+1);
m=read();
pos[1]=1;
scanf("%s",s+1);
len[1]=strlen(s+1);
siji(i,2,m) {
pos[i]=len[i-1]+pos[i-1];
scanf("%s",s+pos[i]);
len[i]=strlen(s+pos[i]);
}
siji(i,1,m) {
ins(i);
}
dp[0]=1;
siji(i,1,n) {
int st=max(0,i-1000);
gongzi(j,i-1,st) {
if(dp[j]) {
int x=find(j+1,i);
if(x!=-1) {
dp[i]=1;
id[i]=x;
from[i]=j;
break;
}
}
}
}
int t=n;
while(t!=0) {
ans[++tot]=id[t];
t=from[t];
}
gongzi(i,tot,1) {
siji(k,pos[ans[i]],pos[ans[i]]+len[ans[i]]-1) {
putchar(s[k]);
}
putchar(' ');
}
putchar('\n');
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
solve();
}
Word puzzles are usually simple and very entertaining for all ages. They are so entertaining that Pizza-Hut company started using table covers with word puzzles printed on them, possibly with the intent to minimise their client's perception of any possible delay in bringing them their order.
Even though word puzzles may be entertaining to solve by hand, they may become boring when they get very large. Computers do not yet get bored in solving tasks, therefore we thought you could devise a program to speedup (hopefully!) solution finding in such puzzles.
The following figure illustrates the PizzaHut puzzle. The names of the pizzas to be found in the puzzle are: MARGARITA, ALEMA, BARBECUE, TROPICAL, SUPREMA, LOUISIANA, CHEESEHAM, EUROPA, HAVAIANA, CAMPONESA.
Your task is to produce a program that given the word puzzle and words to be found in the puzzle, determines, for each word, the position of the first letter and its orientation in the puzzle.
You can assume that the left upper corner of the puzzle is the origin, (0,0). Furthemore, the orientation of the word is marked clockwise starting with letter A for north (note: there are 8 possible directions in total).
The first line of input consists of three positive numbers, the number of lines, 0 < L <= 1000, the number of columns, 0 < C <= 1000, and the number of words to be found, 0 < W <= 1000. The following L input lines, each one of size C characters, contain the word puzzle. Then at last the W words are input one per line.
Your program should output, for each word (using the same order as the words were input) a triplet defining the coordinates, line and column, where the first letter of the word appears, followed by a letter indicating the orientation of the word according to the rules define above. Each value in the triplet must be separated by one space only.
20 20 10
QWSPILAATIRAGRAMYKEI
AGTRCLQAXLPOIJLFVBUQ
TQTKAZXVMRWALEMAPKCW
LIEACNKAZXKPOTPIZCEO
FGKLSTCBTROPICALBLBC
JEWHJEEWSMLPOEKORORA
LUPQWRNJOAAGJKMUSJAE
KRQEIOLOAOQPRTVILCBZ
QOPUCAJSPPOUTMTSLPSF
LPOUYTRFGMMLKIUISXSW
WAHCPOIYTGAKLMNAHBVA
EIAKHPLBGSMCLOGNGJML
LDTIKENVCSWQAZUAOEAL
HOPLPGEJKMNUTIIORMNC
LOIUFTGSQACAXMOPBEIO
QOASDHOPEPNBUYUYOBXB
IONIAELOJHSWASMOUTRK
HPOIYTJPLNAQWDRIBITG
LPOINUYMRTEMPTMLMNBO
PAFCOPLHAVAIANALBPFS
MARGARITA
ALEMA
BARBECUE
TROPICAL
SUPREMA
LOUISIANA
CHEESEHAM
EUROPA
HAVAIANA
CAMPONESA
0 15 G
2 11 C
7 18 A
4 8 C
16 13 B
4 15 E
10 3 D
5 1 E
19 7 C
11 11 H
忽然不明白为什么要存反建图
正着存串也可以啊,然后找到了结束位置就减去对应的向量就好
对于每一行每一列每一对角线跑AC自动机就好
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#define siji(i,x,y) for(int i=(x);i<=(y);++i)
#define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
#define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
#define MAXN 10005
#define MAXM 100005
#define mod 1000000007
//#define ivorysi
using namespace std;
typedef long long ll;
ll read() {
ll res=0,neg=1;
char c=getchar();
while(c<'0' || c>'9') {
if(c=='-') neg=-1;
c=getchar();
}
while(c>='0' && c<='9') {
res=res*10+c-'0';
c=getchar();
}
return res*neg;
}
struct node {
int next[26];
int danger,prev;
}tr[1000005];
int l,c,w,cnt=1,fa[1005];
int ansx[1005],ansy[1005],d[1005],len[1005];
char *dir="ABCDEFGH",str[1005],puzzle[1005][1005];;
int dx[]={-1,-1,0,1,1,1,0,-1};
int dy[]={0,1,1,1,0,-1,-1,-1};
int getfa(int x) {
return fa[x]==x ? x:fa[x]=getfa(fa[x]);
}
void ins(int x) {
int p=1;
siji(i,1,len[x]) {
if(tr[p].next[str[i]-'A']==0) {
tr[p].next[str[i]-'A']=++cnt;
}
p=tr[p].next[str[i]-'A'];
}
if(tr[p].danger) {
fa[getfa(x)]=getfa(tr[p].danger);
}
else {
tr[p].danger=x;
}
}
queue<int> que;
void buildfail() {
tr[1].prev=1;
siji(i,0,25) {
if(tr[1].next[i]==0) {
tr[1].next[i]=1;
}
else {
tr[tr[1].next[i]].prev=1;
que.push(tr[1].next[i]);
}
}
while(!que.empty()) {
int now=que.front();que.pop();
siji(i,0,25) {
int z=tr[now].next[i],l=tr[now].prev;
l=tr[l].next[i];
if(z!=0) {
que.push(z);
tr[z].prev=l;
}
else {
tr[now].next[i]=l;
}
}
if(tr[now].danger==0 && tr[tr[now].prev].danger) {
tr[now].danger=tr[tr[now].prev].danger;
}
}
}
void solve(int a,int b,int t) {
int p=1;
while(1) {
if(a<=0 || a>l) break;
if(b<=0 || b>c) break;
p=tr[p].next[puzzle[a][b]-'A'];
int ap=p;
while(tr[ap].danger) {
int k=tr[ap].danger;
ansx[k]=a-dx[t]*(len[k]-1);
ansy[k]=b-dy[t]*(len[k]-1);
d[k]=t;
ap=tr[ap].prev;
}
a+=dx[t];
b+=dy[t];
}
}
void solve() {
l=read();c=read();w=read();
siji(i,1,l) {
scanf("%s",puzzle[i]+1);
}
siji(i,1,w) {
fa[i]=i;
scanf("%s",str+1);
len[i]=strlen(str+1);
ins(i);
}
buildfail();
siji(t,0,7) {
siji(j,1,c) {
solve(1,j,t);
solve(l,j,t);
}
siji(i,1,l) {
solve(i,1,t);
solve(i,c,t);
}
}
siji(i,1,w) {
printf("%d %d %c\n",ansx[i]-1,ansy[i]-1,dir[d[i]]);
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
solve();
}
In the Christian religion, the Trinity is the union of the Father, the Son, and the
Holy Spirit in one God.Recently in a far-far-away country, a new word "Hrinity" was created and bec a me very popular. "Hrinity" means "The son is the father, and the father is the son." But the word "Hrinity" has nothing to do with God or any religion. It's about a writer and his son. When the son wasin highschool, he failed all exams of all courses. As a none famous writer, the son's worrying father carried out a bold plan: he wrote a long novel and declared that it's his 16 year old son's work. An idiot kid can write a long novel? That made a press interested and the press published the novel. Since then, the son got famous and rich, and his father has been keep writing novels and articles on his son's name.But the father doesn
't trust his son because his son is a punk.
Afraid of being treated badly by his son when becomingold, the father embedded "text finger prints" in all the novels and articles. If the son treats him badly, the father will stand out and declare that his son is a fake writer. The father can point out the "text finger prints" in those works to prove that he actually is the author. A text finger print is a delicate sentence which if you add、delete or change the
punctuations in it, it's meaning will become totally different. In all his works, the father write many text finger prints whose meaning can be changed into something like
"my father wrote this article"、"I am a fake writer", etc.
In case of forgetting where the finger prints are, the father needs a computer program to find
out how many finger prints are there in a given article. He offers $20,000,000 to buy the program. Do you want this money?To simplify the problem, we assume that the articles are all written in capital English letters and without blanks.
There are multiple test
cases. The first line in the input is an integer T ( T<= 15)
indicating the number of test cases.
For each test case:The first line is a integer n( 0 < n <= 2500) indicating the number of
text finger prints.
Then n lines follows, each represents a text finger print. It’s guaranteed that these n strings are all different. A finger print at least consists of one letter.The last line of a test case is thearticle. The text finger prints and the article may be described in a compressed format. A compressed string consists of capital letters and “compressors”. A “compressor” is in the following format:
[qx]
q is a number( 0 < q <= 5,000,000)and x is a capital letter. It means q consecutive letter xs in the original uncompressed string. For example, [6K] means ‘KKKKKK’ in the original string. So, if a compressed string is like:
AB[2D]E[7K]G
It actually is ABDDEKKKKKKKG after decompressed to original format.
The length of the article is at least 1 and at most 5,100,000, no matter in the compressed format or a
fter it is decompressed to original format.The length of a text finger printb is no more than 1,100, no matter compressed or original.
For each test case, print an integer K in a line meaning that the article includes K text finger prints.
PLEASE NOTE: If finger print s1 is a sub string of finger print s2 and s2 is included in the article,then s1 doesn't count(s1 can be regarded as doesn't exists).
Multiple appearances of a finger print in the article are just counted as one.
4
2
AB
DCB
DACB
3
A
AB
ABC
DABC
2
[2A]
[3A]B
[5A]B
[4A]B
3
AB
CD
EF
ABCDEF
0
1
1
3
这道题的格式调的我累死了
一开始我还以为模式串总长度是5100000,每次清一遍0就1s了啊!!!!然后我很愉快的TLE了
还很sb的改改改
这道题先建一个AC自动机
然后给每个点打上访问标记,之后对于每个访问过的节点把它到父亲的路上和后缀节点都标记为不合法
但是!这道题有问题
它不传prev节点的结束标记,对于这样一个数据,它的答案和题面不符
1
2
ABCD
BC
ABC
会输出0而不会输出1
这道题不是很好
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#define siji(i,x,y) for(int i=(x);i<=(y);++i)
#define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
#define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
#define MAXN 5100005
#define MAXM 100005
#define mod 1000000007
//#define ivorysi
using namespace std;
typedef long long ll;
ll read() {
ll res=0,neg=1;
char c=getchar();
while(c<'0' || c>'9') {
if(c=='-') neg=-1;
c=getchar();
}
while(c>='0' && c<='9') {
res=res*10+c-'0';
c=getchar();
}
return res*neg;
}
struct node {
int next[26];
int prev,fa;
}tr[200005];
int nodecnt=1,n,T;
bool ed[200005],vis[200005],lab[200005];
char s[MAXN];
void ins(int x) {
int len=strlen(s+1),p=1;
siji(i,1,len) {
int cnt=0;
bool flag=0;
if(s[i]=='[') {
flag=1;
++i;
while(s[i]>='0' && s[i]<='9') {
cnt=cnt*10+s[i]-'0';
++i;
}
}
else cnt=1;
siji(j,1,cnt) {
if(tr[p].next[s[i]-'A']==0) {
tr[p].next[s[i]-'A']=++nodecnt;
tr[nodecnt].fa=p;
}
p=tr[p].next[s[i]-'A'];
}
if(flag) {
++i;
}
}
ed[p]=1;
}
queue<int> que;
void buildfail() {
tr[1].prev=1;
siji(i,0,25) {
if(tr[1].next[i]==0) {
tr[1].next[i]=1;
}
else {
tr[tr[1].next[i]].prev=1;
que.push(tr[1].next[i]);
}
}
while(!que.empty()) {
int now=que.front();que.pop();
siji(i,0,25) {
int v=tr[now].next[i],l=tr[now].prev;
if(v==0) {
tr[now].next[i]=tr[l].next[i];
}
else {
tr[v].prev=tr[l].next[i];
que.push(v);
}
}
//if(ed[tr[now].prev]) ed[now]=1;
}
}
void process() {
int len=strlen(s+1),p=1;
siji(i,1,len) {
int cnt=0;
bool flag=0;
if(s[i]=='[') {
++i;
flag=1;
while(s[i]>='0' && s[i]<='9') {
cnt=cnt*10+s[i]-'0';
++i;
}
}
else cnt=1;
siji(j,1,cnt) {
p=tr[p].next[s[i]-'A'];
if(ed[p]) vis[p]=1;
}
if(flag) ++i;
}
}
void dfs(int u) {
if(lab[u] || u==1 || u==0) return;
lab[u]=1;
vis[u]=0;
dfs(tr[u].fa);
dfs(tr[u].prev);
}
void solve() {
nodecnt=1;
memset(tr,0,sizeof(tr));
memset(ed,0,sizeof(ed));
memset(vis,0,sizeof(vis));
memset(lab,0,sizeof(lab));
n=read();
siji(i,1,n) {
scanf("%s",s+1);
ins(i);
}
buildfail();
scanf("%s",s+1);
process();
int ans=0;
siji(i,1,nodecnt) {
if((!lab[i]) && vis[i]) {
dfs(tr[i].fa);
dfs(tr[i].prev);
}
}
siji(i,1,nodecnt) {
if(vis[i]) ++ans;
}
printf("%d\n",ans);
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
T=read();
while(T--) {
solve();
}
}
小t非常感谢大家帮忙解决了他的上一个问题。然而病毒侵袭持续中。在小t的不懈努力下,他发现了网路中的“万恶之源”。这是一个庞大的病毒网站,他有着好多好多的病毒,但是这个网站包含的病毒很奇怪,这些病毒的特征码很短,而且只包含“英文大写字符”。当然小t好想好想为民除害,但是小t从来不打没有准备的战争。知己知彼,百战不殆,小t首先要做的是知道这个病毒网站特征:包含多少不同的病毒,每种病毒出现了多少次。大家能再帮帮他吗?
第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。
接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。
在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。
按以下格式每行一个,输出每个病毒出现次数。未出现的病毒不需要输出。
病毒特征码: 出现次数
冒号后有一个空格,按病毒特征码的输入顺序进行输出。
3
AA
BB
CC
ooxxCC%dAAAoen....END
AA: 2
CC: 1
Hit:
题目描述中没有被提及的所有情况都应该进行考虑。比如两个病毒特征码可能有相互包含或者有重叠的特征码段。
计数策略也可一定程度上从Sample中推测。
垃圾题面,多组数据还不告诉,垃圾题面!!!
这道题我们记录每个点被访问了多少次,按照bfs序的倒序向上累加到prev结点上就可以了(最近的prev就可以,道理和kmp差不多)
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#define siji(i,x,y) for(int i=(x);i<=(y);++i)
#define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
#define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
#define MAXN 50005
#define MAXM 100005
#define mod 1000000007
//#define ivorysi
using namespace std;
typedef long long ll;
ll read() {
ll res=0,neg=1;
char c=getchar();
while(c<'0' || c>'9') {
if(c=='-') neg=-1;
c=getchar();
}
while(c>='0' && c<='9') {
res=res*10+c-'0';
c=getchar();
}
return res*neg;
}
struct node {
int next[26];
int prev;
}tr[MAXN];
int nodecnt=1,n;
int pos[MAXN],vis[MAXN],line[MAXN],tot,ans[1005];
char s[2000005],str[1005][55];
void ins(int x) {
int p=1;
int len=strlen(str[x]+1);
siji(i,1,len) {
if(tr[p].next[str[x][i]-'A']==0) {
tr[p].next[str[x][i]-'A']=++nodecnt;
}
p=tr[p].next[str[x][i]-'A'];
}
pos[p]=x;
}
queue<int> que;
void buildfail() {
tr[1].prev=1;
siji(i,0,25) {
if(tr[1].next[i]==0) {
tr[1].next[i]=1;
}
else {
int k=tr[1].next[i];
tr[k].prev=1;
que.push(k);
}
}
while(!que.empty()) {
int now=que.front();que.pop();
line[++tot]=now;
siji(i,0,25) {
int l=tr[now].prev,z=tr[now].next[i];
if(z==0) {
tr[now].next[i]=tr[l].next[i];
}
else {
tr[z].prev=tr[l].next[i];
que.push(z);
}
}
}
}
bool solve() {
if(scanf("%d",&n)==EOF) return false;
memset(tr,0,sizeof(tr));
nodecnt=1;
memset(pos,0,sizeof(pos));
memset(vis,0,sizeof(vis));
memset(line,0,sizeof(line));
tot=0;
memset(ans,0,sizeof(ans));
siji(i,1,n) {
scanf("%s",str[i]+1);
ins(i);
}
buildfail();
scanf("%s",s+1);
int len=strlen(s+1);
int p=1;
siji(i,1,len) {
if(s[i]<'A' || s[i]>'Z') p=1;
else {
p=tr[p].next[s[i]-'A'];
}
++vis[p];
}
gongzi(i,tot,1) {
int k=line[i];
vis[tr[k].prev]+=vis[k];
}
siji(i,1,nodecnt) {
ans[pos[i]]=vis[i];
}
siji(i,1,n) {
if(ans[i]>0) {
printf("%s: %d\n",str[i]+1,ans[i]);
}
}
return true;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
while(1) {
if(!solve()) break;
}
}
顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆序为“cba”,不相同)。
输入长度为n的串S,求S的最长双回文子串T,即可将T分为两部分X,Y,(|X|,|Y|≥1)且X和Y都是回文串。
一行由小写英文字母组成的字符串S。
一行一个整数,表示最长双回文子串的长度。
baacaabbacabb
12
从第二个字符开始的字符串aacaabbacabb可分为aacaa与bbacabb两部分,且两者都是回文串。
对于100%的数据,2≤|S|≤10^5
2015.4.25新加数据一组
先跑马拉车,然后dp
f[i]表示从i往前能有多长的回文串,g[i]表示从i往后能有多少的回文串
更新的时候单调队列优化
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#define siji(i,x,y) for(int i=(x);i<=(y);++i)
#define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
#define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
#define MAXN 100005
#define mod 1000000007
//#define ivorysi
using namespace std;
typedef long long ll;
ll read() {
ll res=0,neg=1;
char c=getchar();
while(c<'0' || c>'9') {
if(c=='-') neg=-1;
c=getchar();
}
while(c>='0' && c<='9') {
res=res*10+c-'0';
c=getchar();
}
return res*neg;
}
char s[MAXN],str[MAXN*2];
int f[MAXN],g[MAXN],len,r[MAXN*2];
int q[MAXN*2],h,t;
bool solve() {
scanf("%s",s+1);
len=strlen(s+1);
siji(i,1,len) {
str[i*2-1]='$';
str[i*2]=s[i];
}
str[len*2+1]='$';
int pos=0,maxright=0;
siji(i,1,len*2+1) {
if(maxright > i) r[i]=min(r[2*pos-i],maxright-i+1);
r[i]=max(r[i],1);
while(i-r[i]>=1 && i+r[i]<=len*2+1 && str[i-r[i]]==str[i+r[i]]) ++r[i];
if(i+r[i]-1>maxright) {
maxright=i+r[i]-1;
pos=i;
}
}
h=1,t=0;
siji(i,1,len) {
while(h<=t) {//这里是h<=t 不合法就全部清空了
if(q[h]+r[q[h]]-1 < i*2) ++h;
else break;
}
if(h<=t) {
f[i]=(i*2-q[h])+1;
}
else f[i]=1;
if(h>t || q[t]+r[q[t]]-1 < i*2-1+r[i*2-1]-1) {
q[++t]=i*2-1;
}
if(h>t || q[t]+r[q[t]]-1 < i*2+r[i*2]-1) {
q[++t]=i*2;
}
}
h=1,t=0;
gongzi(i,len,1) {
while(h<=t) {
if(q[h]-r[q[h]]+1 > i*2) ++h;
else break;
}
if(h<=t) {
g[i]=(q[h]-i*2)+1;
}
else g[i]=1;
if(h>t || q[t]-r[q[t]]+1 > i*2-1-r[i*2-1]+1) {
q[++t]=i*2-1;
}
if(h>t || q[t]-r[q[t]]+1 > i*2-r[i*2]+1) {
q[++t]=i*2;
}
}
int ans=0;
xiaosiji(i,1,len) {
ans=max(f[i]+g[i+1],ans);
}
printf("%d\n",ans);
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
solve();
}
In an English class Nick had nothing to do at all, and remembered about wonderful strings called palindromes. We should remind you that a string is called a palindrome if it can be read the same way both from left to right and from right to left. Here are examples of such strings: «eye», «pop», «level», «aba», «deed», «racecar», «rotor», «madam».
Nick started to look carefully for all palindromes in the text that they were reading in the class. For each occurrence of each palindrome in the text he wrote a pair — the position of the beginning and the position of the ending of this occurrence in the text. Nick called each occurrence of each palindrome he found in the text subpalindrome. When he found all the subpalindromes, he decided to find out how many different pairs among these subpalindromes cross. Two subpalindromes cross if they cover common positions in the text. No palindrome can cross itself.
Let's look at the actions, performed by Nick, by the example of text «babb». At first he wrote out all subpalindromes:
• «b» — 1..1
• «bab» — 1..3
• «a» — 2..2
• «b» — 3..3
• «bb» — 3..4
• «b» — 4..4
Then Nick counted the amount of different pairs among these subpalindromes that cross. These pairs were six:
1. 1..1 cross with 1..3
2. 1..3 cross with 2..2
3. 1..3 cross with 3..3
4. 1..3 cross with 3..4
5. 3..3 cross with 3..4
6. 3..4 cross with 4..4
Since it's very exhausting to perform all the described actions manually, Nick asked you to help him and write a program that can find out the amount of different subpalindrome pairs that cross. Two subpalindrome pairs are regarded as different if one of the pairs contains a subpalindrome that the other does not.
The first input line contains integer n (1 ≤ n ≤ 2·106) — length of the text. The following line contains n lower-case Latin letters (from a to z).
In the only line output the amount of different pairs of two subpalindromes that cross each other. Output the answer modulo 51123987.
4
babb
6
2
aa
2
这道题用到了正难则反的思想
我们先求出一共有多少个回文串他们两两搭配
然后去除掉没有相交部分的字符串
f[i]表示以i为结尾的回文串有多少个
g[i]表示以i为开头的回文串有多少个
这可以用查分统计……
然后将g处理成后缀和
要注意不断的取模……因为数据会很大
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#define siji(i,x,y) for(int i=(x);i<=(y);++i)
#define gongzi(j,x,y) for(int j=(x);j>=(y);--j)
#define xiaosiji(i,x,y) for(int i=(x);i<(y);++i)
#define MAXN 4000005
#define mod 51123987
//#define ivorysi
using namespace std;
typedef long long ll;
ll read() {
ll res=0,neg=1;
char c=getchar();
while(c<'0' || c>'9') {
if(c=='-') neg=-1;
c=getchar();
}
while(c>='0' && c<='9') {
res=res*10+c-'0';
c=getchar();
}
return res*neg;
}
char s[MAXN],str[MAXN*2];
int len,r[MAXN*2],n;
int f[MAXN],g[MAXN];
ll ans;
void solve() {
scanf("%d %s",&n,s+1);
if(n==1) {
puts("0");return;
}
siji(i,1,n) {
str[i*2-1]='$';
str[i*2]=s[i];
}
str[n*2+1]='$';
int pos=0,maxright=0;
siji(i,1,n*2+1) {
if(maxright >= i) r[i]=min(r[2*pos-i],maxright-i+1);
r[i]=max(r[i],1);
while(i-r[i]>=1 && i+r[i]<=n*2+1 && str[i-r[i]]==str[i+r[i]]) {
++r[i];
}
if(i+r[i]-1>maxright) {
maxright=i+r[i]-1;
pos=i;
}
}
siji(i,1,n*2+1) {
if(i%2==0) {
f[i/2]++;
f[(i+r[i]-1)/2+1]--;
g[i/2+1]--;
g[(i-r[i]+1)/2+1]++;
ans+=(r[i]-1)/2+1;
ans%=mod;
}
else {
f[i/2+1]++;
f[(i+r[i]-1)/2+1]--;
g[i/2+1]--;
g[(i-r[i]+1)/2+1]++;
ans+=(r[i]-1)/2;
ans%=mod;
}
}
ans=ans*(ans-1)/2;
ans%=mod;
f[0]=0;f[n+1]=0;
g[0]=0;g[n+1]=0;
siji(i,1,n) {
f[i]+=f[i-1];
f[i]%=mod;
g[i]+=g[i-1];
g[i]%=mod;
}
gongzi(i,n,1) {
g[i]+=g[i+1];
g[i]%=mod;
}
siji(i,1,n-1) {
ans-=(ll)f[i]*g[i+1]%mod;
ans=(ans%mod+mod)%mod;
}
printf("%lld\n",ans);
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
solve();
return 0;
}