bnu j just a string

求一个给定字符串中的由来自前缀集合和后缀集合构成的笛卡尔积中所有元素的魅力值的异或值。   (x,y)的魅力值为字符串x,y中的b的最大长度。  其中 字符串x=字符串a+字符串b   字符串y=字符串b+字符串c.

J. Just A String

Time Limit: 3000ms

Memory Limit: 262144KB

64-bit integer IO format: %lld      Java class name: Main

Submit Status PID: 52516http://app.yinxiang.com/l/ADcOgiLmpRhF2o9MlhmzMeoqfkA_kLO53Tw/

何老师手中有一个字符串,他发现这个字符串有一个神奇的性质,取出一个长为的前缀(就是由的前个字符顺序构成的字符串)和一个长为的后缀(就是由的后个字符顺序构成的字符串)之后,总是存在三个字符串使得,虽然这听起来像是一句废话。

显然三元组不总是唯一的,何老师从所有可能的三元组中找到最长的,很容易知道这样的三元组是唯一的,并且认为的契合度就是,现在你需要帮何老师算出所有的异或和。

这里表示字符串的长度,表示将两个字符串顺序拼接起来后得到的新字符串。

 1 /* ____________________
 2   #include<bits/stdc++.h>
 3   using namespace std;
 4   typedef long long  ll;
 5   typedef pair<ll,ll> pll;
 6   #define pb(x) push_back(x)
 7   typedef unsigned long long  ull;
 8   #define mem(A, X) memset(A, X, sizeof A)
 9   #define ford(i,l,u) for(ll (i)=(ll)(l);(i)>=(ll)(u);--(i))
10   #define foreach(e,x) for(__typeof(x.begin()) e=x.begin();e!=x.end();++e)
11   #define fori(i,l,u) for(ll (i)=(ll)(l);(i)<=(ll)(u);++(i))
12   typedef pair<int,int> pii;
13   #define mp  make_pair
14   #define sec second
15   #define fir first
16
17   const ll mod=1e9+7;
18   const ll Maxn=2e3+10;
19
20
21    ll Next[Maxn];
22
23    void GetNext(char *p,ll m)
24    {
25        Next[0]=Next[1]=0;
26
27        fori(i,1,m-1)
28        {
29         ll j=Next[i];
30         while(j&&p[i]!=p[j]) j=Next[j];
31         Next[i+1]= p[i]==p[j] ? j+1:0;
32        }
33    }
34
35    ll Common[Maxn];
36    void Find(char *s,char *p,ll m)
37    {
38     GetNext(p,m);
39     ll n=strlen(s);
40     //fori (i,0,m-1) cout<<Next[i]<<" ";
41     //cout<<endl;
42     ll j=0;
43     //fori (i,0,m-1) printf("%d ",Next[i]);
44     //printf("\n j: ");
45     fori (i,0,n-1) {
46       while(j&&s[i]!=p[j]) j=Next[j];
47       if(s[i]==p[j]) j++;
48
49       //printf("__%d  i-j+1: %d ",j,i-j+1);
50       if(j==0) Common[i]=0;
51         else Common[i]=j;
52       if(j==m) j=Next[j];// 排除越界访问。
53     }
54     //puts("");
55    }
56
57
58   int main()
59   {
60        std::ios::sync_with_stdio(false);
61        //freopen("in.txt","r",stdin);
62        int T;
63        while(scanf("%d",&T) != EOF)
64        {
65         char s[Maxn];
66         scanf("%s",s);
67         ll n = strlen(s);
68         ll ret=0;
69         fori (j,1,n) {
70           fori(di,0,n-1) Common[di]=0;
71           Find(s, s + (n-j), j);
72           //printf("%s___\n",s + (n - j ));
73          // fori (di, 0, n-1) printf("%d ",Common[di]);
74          // puts("");
75           //puts("");
76           fori (id, 0, n-1) {
77             ll A,B,C,i;
78             B = Common[id];
79             i=id+1;
80             A = i - B;
81             C = j - B;
82             ll temp = A * B * B * C;
83             //cout<<"A B C:"<<A<<" "<<B<<" "<<C<<"  temp: "<<temp<<endl;
84             //cout<<temp<<endl;
85             ret= ret ^ temp;
86           }
87         }
88         printf("%lld\n",ret);
89        }
90     return 0;
91   }
92
93  /*__________
94     analysis:  分析考虑每个f(i,j)的含义,其含义与kmp算法中next数组几乎一致,只是细节上一个下标还有一些对应关系的差别。  之后就是考虑快速得到所有的f值,
95                枚举每一个后缀sufj,对sufj和完整的文本串进行匹配。由于sufj为后缀,即可确定f()中固定的j,而对于sufj和完整文本串匹配的时候,某个Nexti值就确定出来了后缀j与前缀i(后缀j指文本串的下标j,j+1,... n-1 构成的后缀,同理prei)的魅力值。回顾某个确定的后缀j会发现,j是和所有的i=0 1 2 3 ... n-1 一一对应的,所以只需要枚举所有的后缀均和文本串进行一次kmp即可。
96     debug   :  实现的时候,因为是枚举后缀,使用的指针传下标结合模式串的个数的形式,在求next数组的时候要及时在某次匹配完一次完整的模式串时更新下次带检测的位置,不然会由于超出去的位置有字符引起匹配错误。
97     note    :
98   */ 
时间: 2024-11-24 18:41:13

bnu j just a string的相关文章

bnu oj 34985 Elegant String (矩阵+dp)

Elegant String We define a kind of strings as elegant string: among all the substrings of an elegant string, none of them is a permutation of "0, 1,-, k". Let function(n, k) be the number of elegant strings of length n which only contains digits

HDU5008 Boring String Problem(后缀数组 + 二分 + 线段树)

题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5008 Description In this problem, you are given a string s and q queries. For each query, you should answer that when all distinct substrings of string s were sorted lexicographically, which one is

JAVA学习第三十课(经常使用对象API)- String类:类方法练习

intern方法 public class Main { public static void main(String[] args) { String str1 = new String("asd"); String str2 = str1.intern();/* 字符串常量池中有,就返回字符串,没有就创建 */ System.out.println(str2); System.out.println( str1 == str2 ); } } 练习1:字符串数组排序 import j

JAVA学习第三十课(常用对象API)- String类:类方法练习

intern方法 public class Main { public static void main(String[] args) { String str1 = new String("asd"); String str2 = str1.intern();/* 字符串常量池中有,就返回字符串,没有就创建 */ System.out.println(str2); System.out.println( str1 == str2 ); } } 练习1:字符串数组排序 import j

hdu 5008(2014 ACM/ICPC Asia Regional Xi&#39;an Online ) Boring String Problem(后缀数组&amp;二分)

Boring String Problem Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 219    Accepted Submission(s): 45 Problem Description In this problem, you are given a string s and q queries. For each que

lua string

–lua中字符串索引从前往后是1,2,--,从后往前是-1,-2--. –string库中所有的function都不会直接操作字符串,只返回一个结果. [基本函数] 函数 描述 示例 结果 len 计算字符串长度 string.len("abcd") 4 rep 返回字符串s的n个拷贝 string.rep("abcd",2) abcdabcd lower 返回字符串全部字母大写 string.lower("AbcD") abcd upper 返

Lua 之string库

标准string库 基础字符串函数 string.len(s) 返回一个字符串的长度,例如 print(string.len("hello world")) -- 11 string.rep(s, n) 返回一个新的字符串,该字符串是参数s重复n次得到的结果,例如 print(string.rep("go", 3)) -- gogogo string.lower(s) string.upper(s) 字符串大小写转换,例如 print(string.lower(&q

lua的string库与强大的模式匹配

lua原生解释器对字符串的处理能力是十分有限的,强大的字符串操作能力来自于string库.lua的string函数导出在string module中.在lua5.1,同时也作为string类型的成员方法,因此,我们既可以写成string.upper(s), 也可以s:upper(),选择你喜欢的写法. string.len(s)返回s的长度. string.rep(s, n)返回重复s字符串n次的字符串. string.lower(s)返回一份已将大写转成小写的字符串s的拷贝 lower,upp

Lua_第19章 String 库(上)

Lua_第19章String 库 Lua解释器对字符串的支持很有限.一个程序可以创建字符串并连接字符串,但不能截取子串,检查字符串的大小,检测字符串的内容.在 Lua中操纵字符串的功能基本来自于 string 库. String 库中的一些函数是非常简单的:string.len(s)返回字符串 s 的长度;string.rep(s, n)返回重复 n 次字符串 s 的串;你使用 string.rep("a", 2^20)可以创建一个 1M bytes 的字符 串(比如,为了测试需要);