URAL - 1960   Palindromes and Super Abilities

  回文树水题,每次插入时统计数量即可。

  

 #include<bits/stdc++.h>
using namespace std;
#define eps 1e-9
#define For(i,a,b) for(int i=a;i<=b;i++)
#define Fore(i,a,b) for(int i=a;i>=b;i--)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mkp make_pair
#define pb push_back
#define sz size()
#define met(a,b) memset(a,b,sizeof(a))
#define iossy ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define fr freopen
#define pi acos(-1.0)
#define Vector Point
#define fir first
#define sec second
#define endl '\n'
typedef pair<int,int> pii;
const long long linf=1LL<<;
const int iinf=;
const double dinf=1e15;
const int Mod=;
typedef long long ll;
typedef long double ld;
const int maxn=;
struct Pam_Tree{
int nxt[maxn][];
int fail[maxn];
int cnt[maxn];
int num[maxn];
int len[maxn];
int S[maxn];
int lst,n,p;
int newnode(int l) {
For(i,,) nxt[p][i]=;
cnt[p]=;
num[p]=;
len[p]=l;
return p++;
}
void init() {
p=;
newnode();newnode(-);
lst=;n=;S[n]=-;
fail[]=;
}
int get_fail(int x) {
while(S[n-len[x]-]!=S[n]) x=fail[x];
return x;
}
void add(int c) {
S[++n]=c;
int cur=get_fail(lst);
if(!nxt[cur][c]) {
int now=newnode(len[cur]+);
fail[now]=nxt[get_fail(fail[cur])][c];
nxt[cur][c]=now;
num[now]=num[fail[now]]+;
}
lst=nxt[cur][c];
cnt[lst]++;
}
void count() {
Fore(i,p-,) cnt[fail[i]]+=cnt[i];
}
};
Pam_Tree pt;
void Debug(int *a,int l){
cout<<"Debug-----!!!-_-!!----------"<<endl;
For(i,,l) cout<<a[i]<<" ";
cout<<endl;
}
void Debug(ll *a,int l){
cout<<"Debug-----!!!-_-!!----------"<<endl;
For(i,,l) cout<<a[i]<<" ";
cout<<endl;
}
void Debug(double *a,int l){
cout<<"Debug-----!!!-_-!!----------"<<endl;
For(i,,l) cout<<a[i]<<" ";
cout<<endl;
}
void Debug(char *s){
cout<<"Debug-----!!!-_-!!----------"<<endl;
cout<<s+<<endl;
}
int dcmp(double x) {
if(fabs(x)<=eps) return ;
return x<?-:;
}
struct Point{
ll x,y;
Point(ll x=,ll y=):x(x),y(y) {}
Point operator - (const Point &a)const { return Point(x-a.x,y-a.y); }
bool operator < (const Point &a)const { if(a.x==x) return y>a.y; return x<a.x; }
};
ll Dot(Vector a,Vector b){ return a.x*b.x+a.y*b.y; }
ll Cross(Vector a,Vector b){ return a.x*b.y-a.y*b.x; }
double len(Vector a) { return sqrt(Dot(a,a)); }
struct node{
ll x,id;
node(ll x=,ll id=):x(x),id(id) {}
bool operator < (const node &a)const { if(x==a.x) return id<a.id; return x>a.x; }
};
char s[maxn];
void solve() {
pt.init();
scanf("%s",s+);
int l=strlen(s+);
For(i,,l) pt.add(s[i]-'a'),printf("%d ",pt.p-);
puts("");
}
int main() {
int tt=;
while(tt--) solve();
return ;
}

  HDU - 5658  CA Loves Palindromic

  回文树水题,因为长度只有1000,n*n预处理出所有答案即可

  

 #include<bits/stdc++.h>
using namespace std;
#define eps 1e-9
#define For(i,a,b) for(int i=a;i<=b;i++)
#define Fore(i,a,b) for(int i=a;i>=b;i--)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mkp make_pair
#define pb push_back
#define sz size()
#define met(a,b) memset(a,b,sizeof(a))
#define iossy ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define fr freopen
#define pi acos(-1.0)
#define Vector Point
#define fir first
#define sec second
#define endl '\n'
typedef pair<int,int> pii;
const long long linf=1LL<<;
const int iinf=;
const double dinf=1e15;
const int Mod=;
typedef long long ll;
typedef long double ld;
const int maxn=;
struct Pam_Tree{
int nxt[maxn][];
int fail[maxn];
int cnt[maxn];
int num[maxn];
int len[maxn];
int S[maxn];
int lst,n,p;
int newnode(int l) {
For(i,,) nxt[p][i]=;
cnt[p]=;
num[p]=;
len[p]=l;
return p++;
}
void init() {
p=;
newnode();newnode(-);
lst=;n=;S[n]=-;
fail[]=;
}
int get_fail(int x) {
while(S[n-len[x]-]!=S[n]) x=fail[x];
return x;
}
void add(int c) {
S[++n]=c;
int cur=get_fail(lst);
if(!nxt[cur][c]) {
int now=newnode(len[cur]+);
fail[now]=nxt[get_fail(fail[cur])][c];
nxt[cur][c]=now;
num[now]=num[fail[now]]+;
}
lst=nxt[cur][c];
cnt[lst]++;
}
void count() {
Fore(i,p-,) cnt[fail[i]]+=cnt[i];
}
};
Pam_Tree pt;
void Debug(int *a,int l){
cout<<"Debug-----!!!-_-!!----------"<<endl;
For(i,,l) cout<<a[i]<<" ";
cout<<endl;
}
void Debug(ll *a,int l){
cout<<"Debug-----!!!-_-!!----------"<<endl;
For(i,,l) cout<<a[i]<<" ";
cout<<endl;
}
void Debug(double *a,int l){
cout<<"Debug-----!!!-_-!!----------"<<endl;
For(i,,l) cout<<a[i]<<" ";
cout<<endl;
}
void Debug(char *s){
cout<<"Debug-----!!!-_-!!----------"<<endl;
cout<<s+<<endl;
}
int dcmp(double x) {
if(fabs(x)<=eps) return ;
return x<?-:;
}
struct Point{
ll x,y;
Point(ll x=,ll y=):x(x),y(y) {}
Point operator - (const Point &a)const { return Point(x-a.x,y-a.y); }
bool operator < (const Point &a)const { if(a.x==x) return y>a.y; return x<a.x; }
};
ll Dot(Vector a,Vector b){ return a.x*b.x+a.y*b.y; }
ll Cross(Vector a,Vector b){ return a.x*b.y-a.y*b.x; }
double len(Vector a) { return sqrt(Dot(a,a)); }
struct node{
ll x,id;
node(ll x=,ll id=):x(x),id(id) {}
bool operator < (const node &a)const { if(x==a.x) return id<a.id; return x>a.x; }
};
char s[maxn];
int ans[][];
void solve() {
pt.init();
scanf("%s",s+);
int l=strlen(s+),r,q;
For(i,,l) {
pt.init();
For(j,i,l) {
pt.add(s[j]-'a');
ans[i][j]=pt.p-;
}
}
scanf("%d",&q);
while(q--) {
scanf("%d%d",&l,&r);
printf("%d\n",ans[l][r]);
}
}
int main() {
int tt=;
cin>>tt;
while(tt--) solve();
return ;
}

  HYSBZ - 3676 回文串

  回文树水题

  

 #include<bits/stdc++.h>
using namespace std;
#define eps 1e-9
#define For(i,a,b) for(int i=a;i<=b;i++)
#define Fore(i,a,b) for(int i=a;i>=b;i--)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mkp make_pair
#define pb push_back
#define sz size()
#define met(a,b) memset(a,b,sizeof(a))
#define iossy ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define fr freopen
#define pi acos(-1.0)
#define Vector Point
#define fir first
#define sec second
#define endl '\n'
typedef pair<int,int> pii;
const long long linf=1LL<<;
const int iinf=;
const double dinf=1e15;
const int Mod=;
typedef long long ll;
typedef long double ld;
const int maxn=;
struct Pam_Tree{
int nxt[maxn][];
int fail[maxn];
int cnt[maxn];
int num[maxn];
int len[maxn];
int S[maxn];
int lst,n,p;
int newnode(int l) {
For(i,,) nxt[p][i]=;
cnt[p]=;
num[p]=;
len[p]=l;
return p++;
}
void init() {
p=;
newnode();newnode(-);
lst=;n=;S[n]=-;
fail[]=;
}
int get_fail(int x) {
while(S[n-len[x]-]!=S[n]) x=fail[x];
return x;
}
void add(int c) {
S[++n]=c;
int cur=get_fail(lst);
if(!nxt[cur][c]) {
int now=newnode(len[cur]+);
fail[now]=nxt[get_fail(fail[cur])][c];
nxt[cur][c]=now;
num[now]=num[fail[now]]+;
}
lst=nxt[cur][c];
cnt[lst]++;
}
void count() {
Fore(i,p-,) cnt[fail[i]]+=cnt[i];
}
ll ans() {
ll ans=;
Fore(i,p-,) {
ans=max(1LL*cnt[i]*len[i],ans);
}
return ans;
}
};
Pam_Tree pt;
void Debug(int *a,int l){
cout<<"Debug-----!!!-_-!!----------"<<endl;
For(i,,l) cout<<a[i]<<" ";
cout<<endl;
}
void Debug(ll *a,int l){
cout<<"Debug-----!!!-_-!!----------"<<endl;
For(i,,l) cout<<a[i]<<" ";
cout<<endl;
}
void Debug(double *a,int l){
cout<<"Debug-----!!!-_-!!----------"<<endl;
For(i,,l) cout<<a[i]<<" ";
cout<<endl;
}
void Debug(char *s){
cout<<"Debug-----!!!-_-!!----------"<<endl;
cout<<s+<<endl;
}
int dcmp(double x) {
if(fabs(x)<=eps) return ;
return x<?-:;
}
struct Point{
ll x,y;
Point(ll x=,ll y=):x(x),y(y) {}
Point operator - (const Point &a)const { return Point(x-a.x,y-a.y); }
bool operator < (const Point &a)const { if(a.x==x) return y>a.y; return x<a.x; }
};
ll Dot(Vector a,Vector b){ return a.x*b.x+a.y*b.y; }
ll Cross(Vector a,Vector b){ return a.x*b.y-a.y*b.x; }
double len(Vector a) { return sqrt(Dot(a,a)); }
struct node{
ll x,id;
node(ll x=,ll id=):x(x),id(id) {}
bool operator < (const node &a)const { if(x==a.x) return id<a.id; return x>a.x; }
};
char s[maxn];
ll ans;
void solve() {
pt.init();
scanf("%s",s+);
int l=strlen(s+),r,q;
For(i,,l) pt.add(s[i]-'a');
pt.count();
printf("%lld\n",pt.ans());
}
int main() {
int tt=;
while(tt--) solve();
return ;
}

  HYSBZ - 2565 最长双回文串

  回文树瞎搞即可,正着插入统计一遍个数,倒着插入统计一遍个数即可

  

 #include<bits/stdc++.h>
using namespace std;
#define eps 1e-9
#define For(i,a,b) for(int i=a;i<=b;i++)
#define Fore(i,a,b) for(int i=a;i>=b;i--)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mkp make_pair
#define pb push_back
#define sz size()
#define met(a,b) memset(a,b,sizeof(a))
#define iossy ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define fr freopen
#define pi acos(-1.0)
#define Vector Point
#define fir first
#define sec second
#define endl '\n'
typedef pair<int,int> pii;
const long long linf=1LL<<;
const int iinf=;
const double dinf=1e15;
const int Mod=;
typedef long long ll;
typedef long double ld;
const int maxn=;
const int MAXN=;
struct Pam_Tree{
int nxt[maxn][];
int fail[maxn];
int cnt[maxn];
int num[maxn];
int len[maxn];
int S[maxn];
int lst,n,p;
int newnode(int l) {
For(i,,) nxt[p][i]=;
cnt[p]=;
num[p]=;
len[p]=l;
return p++;
}
void init() {
p=;
newnode();newnode(-);
lst=;n=;S[n]=-;
fail[]=;
}
int get_fail(int x) {
while(S[n-len[x]-]!=S[n]) x=fail[x];
return x;
}
int add(int c) {
S[++n]=c;
int cur=get_fail(lst);
if(!nxt[cur][c]) {
int now=newnode(len[cur]+);
fail[now]=nxt[get_fail(fail[cur])][c];
nxt[cur][c]=now;
num[now]=num[fail[now]]+;
}
lst=nxt[cur][c];
cnt[lst]++;
return len[lst];
}
void count() {
Fore(i,p-,) cnt[fail[i]]+=cnt[i];
}
};
Pam_Tree pt; void Debug(int *a,int l){
cout<<"Debug-----!!!-_-!!----------"<<endl;
For(i,,l) cout<<a[i]<<" ";
cout<<endl;
}
void Debug(ll *a,int l){
cout<<"Debug-----!!!-_-!!----------"<<endl;
For(i,,l) cout<<a[i]<<" ";
cout<<endl;
}
void Debug(double *a,int l){
cout<<"Debug-----!!!-_-!!----------"<<endl;
For(i,,l) cout<<a[i]<<" ";
cout<<endl;
}
void Debug(char *s){
cout<<"Debug-----!!!-_-!!----------"<<endl;
cout<<s+<<endl;
}
int dcmp(double x) {
if(fabs(x)<=eps) return ;
return x<?-:;
}
struct Point{
ll x,y;
Point(ll x=,ll y=):x(x),y(y) {}
Point operator - (const Point &a)const { return Point(x-a.x,y-a.y); }
bool operator < (const Point &a)const { if(a.x==x) return y>a.y; return x<a.x; }
};
ll Dot(Vector a,Vector b){ return a.x*b.x+a.y*b.y; }
ll Cross(Vector a,Vector b){ return a.x*b.y-a.y*b.x; }
double len(Vector a) { return sqrt(Dot(a,a)); }
struct node{
ll x,id;
node(ll x=,ll id=):x(x),id(id) {}
bool operator < (const node &a)const { if(x==a.x) return id<a.id; return x>a.x; }
};
int ans,ansl[MAXN],ansr[MAXN];
char s[MAXN];
void solve() {
pt.init();
scanf("%s",s+);
int l=strlen(s+);
For(i,,l) ansl[i]=pt.add(s[i]-'a');
pt.init();
Fore(i,l,) ansr[i]=pt.add(s[i]-'a');
For(i,,l-) ans=max(ansl[i]+ansr[i+],ans);
cout<<ans<<endl;
}
int main() {
int tt=;
while(tt--) solve();
return ;
}

  HYSBZ - 2160 拉拉队排练

  回文树插入后统计长度回文子串的长度和数量,排序后直接求前k个乘积即可

  

 #include<bits/stdc++.h>
using namespace std;
#define eps 1e-9
#define For(i,a,b) for(int i=a;i<=b;i++)
#define Fore(i,a,b) for(int i=a;i>=b;i--)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mkp make_pair
#define pb push_back
#define sz size()
#define met(a,b) memset(a,b,sizeof(a))
#define iossy ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define fr freopen
#define pi acos(-1.0)
#define Vector Point
#define fir first
#define sec second
#define endl '\n'
typedef pair<int,int> pii;
const long long linf=1LL<<;
const int iinf=;
const double dinf=1e15;
const int Mod=;
typedef long long ll;
typedef long double ld;
const int maxn=;
const int MAXN=;
struct Pam_Tree{
int nxt[maxn][];
int fail[maxn];
int cnt[maxn];
int num[maxn];
int len[maxn];
int S[maxn];
int lst,n,p;
int newnode(int l) {
For(i,,) nxt[p][i]=;
cnt[p]=;
num[p]=;
len[p]=l;
return p++;
}
void init() {
p=;
newnode();newnode(-);
lst=;n=;S[n]=-;
fail[]=;
}
int get_fail(int x) {
while(S[n-len[x]-]!=S[n]) x=fail[x];
return x;
}
int add(int c) {
S[++n]=c;
int cur=get_fail(lst);
if(!nxt[cur][c]) {
int now=newnode(len[cur]+);
fail[now]=nxt[get_fail(fail[cur])][c];
nxt[cur][c]=now;
num[now]=num[fail[now]]+;
}
lst=nxt[cur][c];
cnt[lst]++;
return len[lst];
}
void count() {
Fore(i,p-,) cnt[fail[i]]+=cnt[i];
}
};
Pam_Tree pt; void Debug(int *a,int l){
cout<<"Debug-----!!!-_-!!----------"<<endl;
For(i,,l) cout<<a[i]<<" ";
cout<<endl;
}
void Debug(ll *a,int l){
cout<<"Debug-----!!!-_-!!----------"<<endl;
For(i,,l) cout<<a[i]<<" ";
cout<<endl;
}
void Debug(double *a,int l){
cout<<"Debug-----!!!-_-!!----------"<<endl;
For(i,,l) cout<<a[i]<<" ";
cout<<endl;
}
void Debug(char *s){
cout<<"Debug-----!!!-_-!!----------"<<endl;
cout<<s+<<endl;
}
int dcmp(double x) {
if(fabs(x)<=eps) return ;
return x<?-:;
}
struct Point{
ll x,y;
Point(ll x=,ll y=):x(x),y(y) {}
Point operator - (const Point &a)const { return Point(x-a.x,y-a.y); }
bool operator < (const Point &a)const { if(a.x==x) return y>a.y; return x<a.x; }
};
ll Dot(Vector a,Vector b){ return a.x*b.x+a.y*b.y; }
ll Cross(Vector a,Vector b){ return a.x*b.y-a.y*b.x; }
double len(Vector a) { return sqrt(Dot(a,a)); }
struct node{
ll x,id;
node(ll x=,ll id=):x(x),id(id) {}
bool operator < (const node &a)const { if(x==a.x) return id<a.id; return x>a.x; }
};
struct Node{
int l;
ll x;
bool operator < (const Node &a)const {
if(l==a.l) return x<a.x;
return l>a.l;
}
};
ll quick_pow(ll a,ll b) {
ll base=;
while(b) {
if(b&) base=base*a%Mod;
a=a*a%Mod;b>>=;
}
return base%Mod;
}
char s[maxn];
int l,rt;
ll k;
Node ans[maxn];
void solve() {
pt.init();rt=;
cin>>l>>k;
scanf("%s",s+);
For(i,,l) pt.add(s[i]-'a');
pt.count();
For(i,,pt.p-){
if(pt.len[i]% ) ans[rt].l=pt.len[i],ans[rt++].x=pt.cnt[i];
}
sort(ans+,ans+rt);
ll cur=;
// For(i,1,rt-1) cout<<ans[i].l<<" "<<ans[i].x<<endl;
For(i,,rt-) {
if(k==) break;
if(k<=ans[i].x) cur=(quick_pow(ans[i].l,k)%Mod*cur)%Mod,k=;
else cur=(quick_pow(ans[i].l,ans[i].x)*cur%Mod)%Mod,k-=ans[i].x;
}
if(k) cout<<-<<endl;
else cout<<cur%Mod<<endl;
}
int main() {
int tt=;
while(tt--) solve();
return ;
}

  HDU 5157 Harry and magic string

  求不向交的回文子串的对数

  直接将整个串正向插入,求每次插入时以该位置为右端点的回文子串有多少个,

  再将整个串反向插入到回文树中,同样统计子串的个数,最后统计求和即可

  

 #include<bits/stdc++.h>
using namespace std;
#define eps 1e-9
#define For(i,a,b) for(int i=a;i<=b;i++)
#define Fore(i,a,b) for(int i=a;i>=b;i--)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mkp make_pair
#define pb push_back
#define sz size()
#define met(a,b) memset(a,b,sizeof(a))
#define iossy ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define fr freopen
#define pi acos(-1.0)
#define Vector Point
#define fir first
#define sec second
#define endl '\n'
typedef pair<int,int> pii;
const long long linf=1LL<<;
const int iinf=;
const double dinf=1e15;
const int Mod=;
typedef long long ll;
typedef long double ld;
const int maxn=;
const int MAXN=;
struct Pam_Tree{
vector<pii >nxt[maxn];
int fail[maxn];
int cnt[maxn];
int num[maxn];
int len[maxn];
int S[maxn];
int lst,n,p,x;
int newnode(int l) {
nxt[p].clear();
cnt[p]=;
num[p]=;
len[p]=l;
return p++;
}
void init() {
p=;
newnode();newnode(-);
lst=;n=;S[n]=-;
fail[]=;
}
int find(int cur,int c){
For(i,,nxt[cur].sz) {
if(nxt[cur][i-].fir==c) return nxt[cur][i-].sec;
}
return ;
}
int get_fail(int x) {
while(S[n-len[x]-]!=S[n]) x=fail[x];
return x;
}
int add(int c) {
S[++n]=c;
int cur=get_fail(lst);
x=find(cur,c);
if(!x) {
int now=newnode(len[cur]+);
fail[now]=find(get_fail(fail[cur]),c);
nxt[cur].pb(mkp(c,now));
num[now]=num[fail[now]]+;
x=now;
}
lst=x;
cnt[lst]++;
return num[lst];
}
ll count() {
Fore(i,p-,) cnt[fail[i]]+=cnt[i],cnt[fail[i]]%=Mod;
}
};
Pam_Tree pt;
ll ans[maxn],ans2;
ll cnt1,cnt2,cnt;
char s[maxn];
int n;
void solve() {
while(~scanf("%s",s+)){
pt.init();met(ans,);
int l=strlen(s+);cnt1=;cnt2=;
For(i,,l) ans[i]=ans[i-]+pt.add(s[i]-'a');
cnt2=pt.count();
pt.init();
Fore(i,l,) ans2=pt.add(s[i]-'a'),cnt1=cnt1+ans2*ans[i-];
cout<<cnt1<<endl;
}
}
int main() {
int tt=;
while(tt--) solve();
return ;
}

  CodeForces 17E

  题目大意:求相交的回文子串有多少对

  直接考虑相交不好考虑,可以反着来,用回文子串的对数减去不相交的回文子串的数量即可,回文树搞搞就行。

  题目内存要求较高,可以考虑用map或vector来存next数组

  

 #include<bits/stdc++.h>
using namespace std;
#define eps 1e-9
#define For(i,a,b) for(int i=a;i<=b;i++)
#define Fore(i,a,b) for(int i=a;i>=b;i--)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mkp make_pair
#define pb push_back
#define sz size()
#define met(a,b) memset(a,b,sizeof(a))
#define iossy ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define fr freopen
#define pi acos(-1.0)
#define Vector Point
#define fir first
#define sec second
#define endl '\n'
typedef pair<int,int> pii;
const long long linf=1LL<<;
const int iinf=;
const double dinf=1e15;
const int Mod=;
typedef long long ll;
typedef long double ld;
const int maxn=;
const int MAXN=;
struct Pam_Tree{
unordered_map<int,int>nxt[];
int fail[maxn];
int cnt[maxn];
int num[maxn];
int len[maxn];
int S[maxn];
int lst,n,p;
int newnode(int l) {
cnt[p]=;
num[p]=;
len[p]=l;
return p++;
}
void init() {
p=;
For(i,,) nxt[i].clear();
newnode();newnode(-);
lst=;n=;S[n]=-;
fail[]=;
}
int get_fail(int x) {
while(S[n-len[x]-]!=S[n]) x=fail[x];
return x;
}
int add(int c) {
S[++n]=c;
int cur=get_fail(lst);
if(!nxt[c][cur]) {
int now=newnode(len[cur]+);
fail[now]=nxt[c][get_fail(fail[cur])];
nxt[c][cur]=now;
num[now]=num[fail[now]]+;
}
lst=nxt[c][cur];
cnt[lst]++;
return num[lst];
}
ll count() {
ll res=;
Fore(i,p-,) cnt[fail[i]]+=cnt[i],cnt[fail[i]]%=Mod;
Fore(i,p-,) res+=cnt[i],res%=Mod;
return res;
}
};
Pam_Tree pt;
ll ans[maxn],ans2;
ll cnt1,cnt2,cnt;
char s[maxn];
int n;
void solve() {
cin>>n;
pt.init();
cin>>s+;met(ans,);
int l=strlen(s+);cnt1=;cnt2=;
For(i,,l) ans[i]=ans[i-]+pt.add(s[i]-'a'),ans[i]%=Mod;
cnt2=pt.count();
pt.init();
Fore(i,l,) ans2=pt.add(s[i]-'a'),cnt1=(cnt1+ans2*ans[i-]%Mod)%Mod;
cout<<((cnt2*1LL*(cnt2-)/)%Mod-cnt1+Mod)%Mod<<endl;
}
int main() {
int tt=;
while(tt--) solve();
return ;
}

  HDU 4426 Palindromic Substring

  将整个串插入回文树中,对于每个人,统计其所有回文子串的价值,排序,最后取第k个

  因为k可能会超int,子串的数量也会超int,所以全用long long了

  

 #include<bits/stdc++.h>
using namespace std;
#define eps 1e-9
#define For(i,a,b) for(int i=a;i<=b;i++)
#define Fore(i,a,b) for(int i=a;i>=b;i--)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mkp make_pair
#define pb push_back
#define sz size()
#define met(a,b) memset(a,b,sizeof(a))
#define iossy ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define fr freopen
#define pi acos(-1.0)
#define Vector Point
#define fir first
#define sec second
#define endl '\n'
typedef pair<int,int> pii;
const long long linf=1LL<<;
const int iinf=;
const double dinf=1e15;
const int Mod=;
typedef long long ll;
typedef long double ld;
const int maxn=;
const int MAXN=;
struct Pam_Tree{
int nxt[maxn][];
int fail[maxn];
int cnt[maxn];
int num[maxn];
int len[maxn];
int S[maxn];
int lst,n,p,x;
int newnode(int l) {
For(i,,) nxt[p][i]=;
cnt[p]=;
num[p]=;
len[p]=l;
return p++;
}
void init() {
p=;
newnode();newnode(-);
lst=;n=;S[n]=-;
fail[]=;
}
int get_fail(int x) {
while(S[n-len[x]-]!=S[n]) x=fail[x];
return x;
}
int add(int c) {
S[++n]=c;
int cur=get_fail(lst);
if(!nxt[cur][c]) {
int now=newnode(len[cur]+);
fail[now]=nxt[get_fail(fail[cur])][c];
nxt[cur][c]=now;
num[now]=num[fail[now]]+;
}
lst=nxt[cur][c];
cnt[lst]++;
return num[lst];
}
ll count() {
Fore(i,p-,) cnt[fail[i]]+=cnt[i],cnt[fail[i]]%=Mod;
}
};
Pam_Tree pt;
int v[][];
ll k[],cnt;
ll f[],u,vv;
map<ll,ll>mp;
void dfs(int now,int x,ll st) {
if(now!= && now!=) mp[st]+=pt.cnt[now];
For(i,,) {
if(pt.nxt[now][i]){
dfs(pt.nxt[now][i],x,(st+v[x][i]*1LL*f[(pt.len[now]+)/]%Mod)%Mod);
}
}
}
map<ll,ll>::iterator it;
int n,m;
char s[];
void solve() {
pt.init();
scanf("%d%d",&n,&m);
scanf("%s",s+);
For(i,,n) pt.add(s[i]-'a');
pt.count();
For(i,,m) {
scanf("%lld",&k[i]);
For(j,,)
scanf("%d",&v[i][j]);
}
For(i,,m) {
mp.clear();
dfs(,i,);dfs(,i,);cnt=k[i];
for(it=mp.begin();it!=mp.end();it++) {
u=(*it).first;vv=(*it).sec;
// cout<<u<<" "<<vv<<endl;
if(cnt-vv>)cnt-=vv;
else {
cnt=;
printf("%lld\n",u%Mod);
break;
}
}
}
}
int main() {
f[]=;
For(i,,) f[i]=f[i-]*26LL%Mod;
int tt=;
cin>>tt;
while(tt--) solve(),cout<<endl;
return ;
}

回文树练习 Part1的更多相关文章

  1. HDU3948 & 回文树模板

    Description: 求本质不同回文子串的个数 Solution: 回文树模板,学一学贴一贴啊... Code: /*================================= # Cre ...

  2. 2014-2015 ACM-ICPC, Asia Xian Regional Contest G The Problem to Slow Down You 回文树

    The Problem to Slow Down You Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjud ...

  3. 【CF245H】Queries for Number of Palindromes(回文树)

    [CF245H]Queries for Number of Palindromes(回文树) 题面 洛谷 题解 回文树,很类似原来一道后缀自动机的题目 后缀自动机那道题 看到\(n\)的范围很小,但是 ...

  4. 【CF17E】Palisection(回文树)

    [CF17E]Palisection(回文树) 题面 洛谷 题解 题意: 求有重叠部分的回文子串对的数量 所谓正难则反 求出所有不重叠的即可 求出以一个位置结束的回文串的数量 和以一个位置为开始的回文 ...

  5. 【SPOJ】NUMOFPAL - Number of Palindromes(Manacher,回文树)

    [SPOJ]NUMOFPAL - Number of Palindromes(Manacher,回文树) 题面 洛谷 求一个串中包含几个回文串 题解 Manacher傻逼题 只是用回文树写写而已.. ...

  6. 【BZOJ2160】拉拉队排练(回文树)

    [BZOJ2160]拉拉队排练(回文树) 题面 BZOJ 题解 看着题目, 直接构建回文树 求出每个回文串的出现次数 直接按照长度\(sort\)一下就行了 然后快速幂算一下答案就出来了 这题貌似可以 ...

  7. 【CF932G】Palindrome Partition(回文树,动态规划)

    [CF932G]Palindrome Partition(回文树,动态规划) 题面 CF 翻译: 给定一个串,把串分为偶数段 假设分为了\(s1,s2,s3....sk\) 求,满足\(s_1=s_k ...

  8. 【BZOJ2342】双倍回文(回文树)

    [BZOJ2342]双倍回文(回文树) 题面 BZOJ 题解 构建出回文树之后 在\(fail\)树上进行\(dp\) 如果一个点代表的回文串长度为\(4\)的倍数 并且存在长度为它的一半的回文后缀 ...

  9. 【BZOJ2565】最长双回文串(回文树)

    [BZOJ2565]最长双回文串(回文树) 题面 BZOJ 题解 枚举断点\(i\) 显然的,我们要求的就是以\(i\)结尾的最长回文后缀的长度 再加上以\(i+1\)开头的最长回文前缀的长度 至于最 ...

随机推荐

  1. 【测试笔记】Redis学习笔记(十二)性能测试

    http://blog.csdn.net/yangcs2009/article/details/50781530 Redis测试服务器一 redis_version:2.8.4 www@iZ23s8a ...

  2. 【BZOJ】2208 [Jsoi2010]连通数

    [题意]给定n个点的有向图,求可达点对数(互相可达算两对,含自身).n<=2000. [算法]强连通分量(tarjan)+拓扑排序+状态压缩(bitset) [题解]这题可以说非常经典了. 1. ...

  3. 【leetcode 简单】 第一百零六题 压缩字符串

    给定一组字符,使用原地算法将其压缩. 压缩后的长度必须始终小于或等于原数组长度. 数组的每个元素应该是长度为1 的字符(不是 int 整数类型). 在完成原地修改输入数组后,返回数组的新长度. 进阶: ...

  4. php中各种hash算法的执行速度比较

    更多内容推荐微信公众号,欢迎关注: PHP中的Hash函数很多,像MD4.MD5.SHA-1.SHA-256.SHA-384.SHA-512等我们比较常见,那么各个哈希的执行速度呢? $algos = ...

  5. 利用Object.defineProperty 简化 Chrome插件本地存储操作

    通常谷歌插件本地存储写法很别扭☹,如 chrome.storage.sync.get(null,function(data){ //todo console.log(data); });  如果get ...

  6. 《区块链100问》第82集:应用类项目Golem

    Golem是第一个基于以太坊区块链打造的计算资源交易平台.通过区块链,Golem能链接全球的算力资源,从而实现计算能力的全球共享.应用所有者和个体用户(算力“请求方”)可以点对点地从其他用户处租用算力 ...

  7. c++细节--section1

    1.register声明的变量为寄存器变量,因此没有地址,不能对它取地址操作. 2.[用错sizeof]当数组作为函数参数传递时,数组会退化为同类型的指针. 3.每个成员在成员初始化列表中只能出现一次 ...

  8. pom可以过滤resource 下的文件

  9. JavaScript新手学习笔记(一)

    1.JavaScript 对大小写敏感. JavaScript 对大小写是敏感的. 当编写 JavaScript 语句时,请留意是否关闭大小写切换键. 函数 getElementById 与 getE ...

  10. java 读取配置文件类

    import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; im ...