URAL - 1960 Palindromes and Super Abilities
回文树水题,每次插入时统计数量即可。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define eps 1e-9 4 #define For(i,a,b) for(int i=a;i<=b;i++) 5 #define Fore(i,a,b) for(int i=a;i>=b;i--) 6 #define lson l,mid,rt<<1 7 #define rson mid+1,r,rt<<1|1 8 #define mkp make_pair 9 #define pb push_back 10 #define sz size() 11 #define met(a,b) memset(a,b,sizeof(a)) 12 #define iossy ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) 13 #define fr freopen 14 #define pi acos(-1.0) 15 #define Vector Point 16 #define fir first 17 #define sec second 18 #define endl '\n' 19 typedef pair<int,int> pii; 20 const long long linf=1LL<<62; 21 const int iinf=1000000009; 22 const double dinf=1e15; 23 const int Mod=998244353; 24 typedef long long ll; 25 typedef long double ld; 26 const int maxn=500005; 27 struct Pam_Tree{ 28 int nxt[maxn][26]; 29 int fail[maxn]; 30 int cnt[maxn]; 31 int num[maxn]; 32 int len[maxn]; 33 int S[maxn]; 34 int lst,n,p; 35 int newnode(int l) { 36 For(i,0,25) nxt[p][i]=0; 37 cnt[p]=0; 38 num[p]=0; 39 len[p]=l; 40 return p++; 41 } 42 void init() { 43 p=0; 44 newnode(0);newnode(-1); 45 lst=0;n=0;S[n]=-1; 46 fail[0]=1; 47 } 48 int get_fail(int x) { 49 while(S[n-len[x]-1]!=S[n]) x=fail[x]; 50 return x; 51 } 52 void add(int c) { 53 S[++n]=c; 54 int cur=get_fail(lst); 55 if(!nxt[cur][c]) { 56 int now=newnode(len[cur]+2); 57 fail[now]=nxt[get_fail(fail[cur])][c]; 58 nxt[cur][c]=now; 59 num[now]=num[fail[now]]+1; 60 } 61 lst=nxt[cur][c]; 62 cnt[lst]++; 63 } 64 void count() { 65 Fore(i,p-1,0) cnt[fail[i]]+=cnt[i]; 66 } 67 }; 68 Pam_Tree pt; 69 void Debug(int *a,int l){ 70 cout<<"Debug-----!!!-_-!!----------"<<endl; 71 For(i,1,l) cout<<a[i]<<" "; 72 cout<<endl; 73 } 74 void Debug(ll *a,int l){ 75 cout<<"Debug-----!!!-_-!!----------"<<endl; 76 For(i,1,l) cout<<a[i]<<" "; 77 cout<<endl; 78 } 79 void Debug(double *a,int l){ 80 cout<<"Debug-----!!!-_-!!----------"<<endl; 81 For(i,1,l) cout<<a[i]<<" "; 82 cout<<endl; 83 } 84 void Debug(char *s){ 85 cout<<"Debug-----!!!-_-!!----------"<<endl; 86 cout<<s+1<<endl; 87 } 88 int dcmp(double x) { 89 if(fabs(x)<=eps) return 0; 90 return x<0?-1:1; 91 } 92 struct Point{ 93 ll x,y; 94 Point(ll x=0,ll y=0):x(x),y(y) {} 95 Point operator - (const Point &a)const { return Point(x-a.x,y-a.y); } 96 bool operator < (const Point &a)const { if(a.x==x) return y>a.y; return x<a.x; } 97 }; 98 ll Dot(Vector a,Vector b){ return a.x*b.x+a.y*b.y; } 99 ll Cross(Vector a,Vector b){ return a.x*b.y-a.y*b.x; } 100 double len(Vector a) { return sqrt(Dot(a,a)); } 101 struct node{ 102 ll x,id; 103 node(ll x=0,ll id=0):x(x),id(id) {} 104 bool operator < (const node &a)const { if(x==a.x) return id<a.id; return x>a.x; } 105 }; 106 char s[maxn]; 107 void solve() { 108 pt.init(); 109 scanf("%s",s+1); 110 int l=strlen(s+1); 111 For(i,1,l) pt.add(s[i]-'a'),printf("%d ",pt.p-2); 112 puts(""); 113 } 114 int main() { 115 int tt=1; 116 while(tt--) solve(); 117 return 0; 118 }
HDU - 5658 CA Loves Palindromic
回文树水题,因为长度只有1000,n*n预处理出所有答案即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define eps 1e-9 4 #define For(i,a,b) for(int i=a;i<=b;i++) 5 #define Fore(i,a,b) for(int i=a;i>=b;i--) 6 #define lson l,mid,rt<<1 7 #define rson mid+1,r,rt<<1|1 8 #define mkp make_pair 9 #define pb push_back 10 #define sz size() 11 #define met(a,b) memset(a,b,sizeof(a)) 12 #define iossy ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) 13 #define fr freopen 14 #define pi acos(-1.0) 15 #define Vector Point 16 #define fir first 17 #define sec second 18 #define endl '\n' 19 typedef pair<int,int> pii; 20 const long long linf=1LL<<62; 21 const int iinf=1000000009; 22 const double dinf=1e15; 23 const int Mod=998244353; 24 typedef long long ll; 25 typedef long double ld; 26 const int maxn=500005; 27 struct Pam_Tree{ 28 int nxt[maxn][26]; 29 int fail[maxn]; 30 int cnt[maxn]; 31 int num[maxn]; 32 int len[maxn]; 33 int S[maxn]; 34 int lst,n,p; 35 int newnode(int l) { 36 For(i,0,25) nxt[p][i]=0; 37 cnt[p]=0; 38 num[p]=0; 39 len[p]=l; 40 return p++; 41 } 42 void init() { 43 p=0; 44 newnode(0);newnode(-1); 45 lst=0;n=0;S[n]=-1; 46 fail[0]=1; 47 } 48 int get_fail(int x) { 49 while(S[n-len[x]-1]!=S[n]) x=fail[x]; 50 return x; 51 } 52 void add(int c) { 53 S[++n]=c; 54 int cur=get_fail(lst); 55 if(!nxt[cur][c]) { 56 int now=newnode(len[cur]+2); 57 fail[now]=nxt[get_fail(fail[cur])][c]; 58 nxt[cur][c]=now; 59 num[now]=num[fail[now]]+1; 60 } 61 lst=nxt[cur][c]; 62 cnt[lst]++; 63 } 64 void count() { 65 Fore(i,p-1,0) cnt[fail[i]]+=cnt[i]; 66 } 67 }; 68 Pam_Tree pt; 69 void Debug(int *a,int l){ 70 cout<<"Debug-----!!!-_-!!----------"<<endl; 71 For(i,1,l) cout<<a[i]<<" "; 72 cout<<endl; 73 } 74 void Debug(ll *a,int l){ 75 cout<<"Debug-----!!!-_-!!----------"<<endl; 76 For(i,1,l) cout<<a[i]<<" "; 77 cout<<endl; 78 } 79 void Debug(double *a,int l){ 80 cout<<"Debug-----!!!-_-!!----------"<<endl; 81 For(i,1,l) cout<<a[i]<<" "; 82 cout<<endl; 83 } 84 void Debug(char *s){ 85 cout<<"Debug-----!!!-_-!!----------"<<endl; 86 cout<<s+1<<endl; 87 } 88 int dcmp(double x) { 89 if(fabs(x)<=eps) return 0; 90 return x<0?-1:1; 91 } 92 struct Point{ 93 ll x,y; 94 Point(ll x=0,ll y=0):x(x),y(y) {} 95 Point operator - (const Point &a)const { return Point(x-a.x,y-a.y); } 96 bool operator < (const Point &a)const { if(a.x==x) return y>a.y; return x<a.x; } 97 }; 98 ll Dot(Vector a,Vector b){ return a.x*b.x+a.y*b.y; } 99 ll Cross(Vector a,Vector b){ return a.x*b.y-a.y*b.x; } 100 double len(Vector a) { return sqrt(Dot(a,a)); } 101 struct node{ 102 ll x,id; 103 node(ll x=0,ll id=0):x(x),id(id) {} 104 bool operator < (const node &a)const { if(x==a.x) return id<a.id; return x>a.x; } 105 }; 106 char s[maxn]; 107 int ans[2005][2005]; 108 void solve() { 109 pt.init(); 110 scanf("%s",s+1); 111 int l=strlen(s+1),r,q; 112 For(i,1,l) { 113 pt.init(); 114 For(j,i,l) { 115 pt.add(s[j]-'a'); 116 ans[i][j]=pt.p-2; 117 } 118 } 119 scanf("%d",&q); 120 while(q--) { 121 scanf("%d%d",&l,&r); 122 printf("%d\n",ans[l][r]); 123 } 124 } 125 int main() { 126 int tt=1; 127 cin>>tt; 128 while(tt--) solve(); 129 return 0; 130 }
回文树水题
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define eps 1e-9 4 #define For(i,a,b) for(int i=a;i<=b;i++) 5 #define Fore(i,a,b) for(int i=a;i>=b;i--) 6 #define lson l,mid,rt<<1 7 #define rson mid+1,r,rt<<1|1 8 #define mkp make_pair 9 #define pb push_back 10 #define sz size() 11 #define met(a,b) memset(a,b,sizeof(a)) 12 #define iossy ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) 13 #define fr freopen 14 #define pi acos(-1.0) 15 #define Vector Point 16 #define fir first 17 #define sec second 18 #define endl '\n' 19 typedef pair<int,int> pii; 20 const long long linf=1LL<<62; 21 const int iinf=1000000009; 22 const double dinf=1e15; 23 const int Mod=998244353; 24 typedef long long ll; 25 typedef long double ld; 26 const int maxn=500005; 27 struct Pam_Tree{ 28 int nxt[maxn][26]; 29 int fail[maxn]; 30 int cnt[maxn]; 31 int num[maxn]; 32 int len[maxn]; 33 int S[maxn]; 34 int lst,n,p; 35 int newnode(int l) { 36 For(i,0,25) nxt[p][i]=0; 37 cnt[p]=0; 38 num[p]=0; 39 len[p]=l; 40 return p++; 41 } 42 void init() { 43 p=0; 44 newnode(0);newnode(-1); 45 lst=0;n=0;S[n]=-1; 46 fail[0]=1; 47 } 48 int get_fail(int x) { 49 while(S[n-len[x]-1]!=S[n]) x=fail[x]; 50 return x; 51 } 52 void add(int c) { 53 S[++n]=c; 54 int cur=get_fail(lst); 55 if(!nxt[cur][c]) { 56 int now=newnode(len[cur]+2); 57 fail[now]=nxt[get_fail(fail[cur])][c]; 58 nxt[cur][c]=now; 59 num[now]=num[fail[now]]+1; 60 } 61 lst=nxt[cur][c]; 62 cnt[lst]++; 63 } 64 void count() { 65 Fore(i,p-1,0) cnt[fail[i]]+=cnt[i]; 66 } 67 ll ans() { 68 ll ans=0; 69 Fore(i,p-1,0) { 70 ans=max(1LL*cnt[i]*len[i],ans); 71 } 72 return ans; 73 } 74 }; 75 Pam_Tree pt; 76 void Debug(int *a,int l){ 77 cout<<"Debug-----!!!-_-!!----------"<<endl; 78 For(i,1,l) cout<<a[i]<<" "; 79 cout<<endl; 80 } 81 void Debug(ll *a,int l){ 82 cout<<"Debug-----!!!-_-!!----------"<<endl; 83 For(i,1,l) cout<<a[i]<<" "; 84 cout<<endl; 85 } 86 void Debug(double *a,int l){ 87 cout<<"Debug-----!!!-_-!!----------"<<endl; 88 For(i,1,l) cout<<a[i]<<" "; 89 cout<<endl; 90 } 91 void Debug(char *s){ 92 cout<<"Debug-----!!!-_-!!----------"<<endl; 93 cout<<s+1<<endl; 94 } 95 int dcmp(double x) { 96 if(fabs(x)<=eps) return 0; 97 return x<0?-1:1; 98 } 99 struct Point{ 100 ll x,y; 101 Point(ll x=0,ll y=0):x(x),y(y) {} 102 Point operator - (const Point &a)const { return Point(x-a.x,y-a.y); } 103 bool operator < (const Point &a)const { if(a.x==x) return y>a.y; return x<a.x; } 104 }; 105 ll Dot(Vector a,Vector b){ return a.x*b.x+a.y*b.y; } 106 ll Cross(Vector a,Vector b){ return a.x*b.y-a.y*b.x; } 107 double len(Vector a) { return sqrt(Dot(a,a)); } 108 struct node{ 109 ll x,id; 110 node(ll x=0,ll id=0):x(x),id(id) {} 111 bool operator < (const node &a)const { if(x==a.x) return id<a.id; return x>a.x; } 112 }; 113 char s[maxn]; 114 ll ans; 115 void solve() { 116 pt.init(); 117 scanf("%s",s+1); 118 int l=strlen(s+1),r,q; 119 For(i,1,l) pt.add(s[i]-'a'); 120 pt.count(); 121 printf("%lld\n",pt.ans()); 122 } 123 int main() { 124 int tt=1; 125 while(tt--) solve(); 126 return 0; 127 }
回文树瞎搞即可,正着插入统计一遍个数,倒着插入统计一遍个数即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define eps 1e-9 4 #define For(i,a,b) for(int i=a;i<=b;i++) 5 #define Fore(i,a,b) for(int i=a;i>=b;i--) 6 #define lson l,mid,rt<<1 7 #define rson mid+1,r,rt<<1|1 8 #define mkp make_pair 9 #define pb push_back 10 #define sz size() 11 #define met(a,b) memset(a,b,sizeof(a)) 12 #define iossy ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) 13 #define fr freopen 14 #define pi acos(-1.0) 15 #define Vector Point 16 #define fir first 17 #define sec second 18 #define endl '\n' 19 typedef pair<int,int> pii; 20 const long long linf=1LL<<62; 21 const int iinf=1000000009; 22 const double dinf=1e15; 23 const int Mod=1000000007; 24 typedef long long ll; 25 typedef long double ld; 26 const int maxn=500005; 27 const int MAXN=500005; 28 struct Pam_Tree{ 29 int nxt[maxn][26]; 30 int fail[maxn]; 31 int cnt[maxn]; 32 int num[maxn]; 33 int len[maxn]; 34 int S[maxn]; 35 int lst,n,p; 36 int newnode(int l) { 37 For(i,0,25) nxt[p][i]=0; 38 cnt[p]=0; 39 num[p]=0; 40 len[p]=l; 41 return p++; 42 } 43 void init() { 44 p=0; 45 newnode(0);newnode(-1); 46 lst=0;n=0;S[n]=-1; 47 fail[0]=1; 48 } 49 int get_fail(int x) { 50 while(S[n-len[x]-1]!=S[n]) x=fail[x]; 51 return x; 52 } 53 int add(int c) { 54 S[++n]=c; 55 int cur=get_fail(lst); 56 if(!nxt[cur][c]) { 57 int now=newnode(len[cur]+2); 58 fail[now]=nxt[get_fail(fail[cur])][c]; 59 nxt[cur][c]=now; 60 num[now]=num[fail[now]]+1; 61 } 62 lst=nxt[cur][c]; 63 cnt[lst]++; 64 return len[lst]; 65 } 66 void count() { 67 Fore(i,p-1,0) cnt[fail[i]]+=cnt[i]; 68 } 69 }; 70 Pam_Tree pt; 71 72 void Debug(int *a,int l){ 73 cout<<"Debug-----!!!-_-!!----------"<<endl; 74 For(i,1,l) cout<<a[i]<<" "; 75 cout<<endl; 76 } 77 void Debug(ll *a,int l){ 78 cout<<"Debug-----!!!-_-!!----------"<<endl; 79 For(i,1,l) cout<<a[i]<<" "; 80 cout<<endl; 81 } 82 void Debug(double *a,int l){ 83 cout<<"Debug-----!!!-_-!!----------"<<endl; 84 For(i,1,l) cout<<a[i]<<" "; 85 cout<<endl; 86 } 87 void Debug(char *s){ 88 cout<<"Debug-----!!!-_-!!----------"<<endl; 89 cout<<s+1<<endl; 90 } 91 int dcmp(double x) { 92 if(fabs(x)<=eps) return 0; 93 return x<0?-1:1; 94 } 95 struct Point{ 96 ll x,y; 97 Point(ll x=0,ll y=0):x(x),y(y) {} 98 Point operator - (const Point &a)const { return Point(x-a.x,y-a.y); } 99 bool operator < (const Point &a)const { if(a.x==x) return y>a.y; return x<a.x; } 100 }; 101 ll Dot(Vector a,Vector b){ return a.x*b.x+a.y*b.y; } 102 ll Cross(Vector a,Vector b){ return a.x*b.y-a.y*b.x; } 103 double len(Vector a) { return sqrt(Dot(a,a)); } 104 struct node{ 105 ll x,id; 106 node(ll x=0,ll id=0):x(x),id(id) {} 107 bool operator < (const node &a)const { if(x==a.x) return id<a.id; return x>a.x; } 108 }; 109 int ans,ansl[MAXN],ansr[MAXN]; 110 char s[MAXN]; 111 void solve() { 112 pt.init(); 113 scanf("%s",s+1); 114 int l=strlen(s+1); 115 For(i,1,l) ansl[i]=pt.add(s[i]-'a'); 116 pt.init(); 117 Fore(i,l,1) ansr[i]=pt.add(s[i]-'a'); 118 For(i,1,l-1) ans=max(ansl[i]+ansr[i+1],ans); 119 cout<<ans<<endl; 120 } 121 int main() { 122 int tt=1; 123 while(tt--) solve(); 124 return 0; 125 }
回文树插入后统计长度回文子串的长度和数量,排序后直接求前k个乘积即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define eps 1e-9 4 #define For(i,a,b) for(int i=a;i<=b;i++) 5 #define Fore(i,a,b) for(int i=a;i>=b;i--) 6 #define lson l,mid,rt<<1 7 #define rson mid+1,r,rt<<1|1 8 #define mkp make_pair 9 #define pb push_back 10 #define sz size() 11 #define met(a,b) memset(a,b,sizeof(a)) 12 #define iossy ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) 13 #define fr freopen 14 #define pi acos(-1.0) 15 #define Vector Point 16 #define fir first 17 #define sec second 18 #define endl '\n' 19 typedef pair<int,int> pii; 20 const long long linf=1LL<<62; 21 const int iinf=1000000009; 22 const double dinf=1e15; 23 const int Mod=19930726; 24 typedef long long ll; 25 typedef long double ld; 26 const int maxn=1000005; 27 const int MAXN=500005; 28 struct Pam_Tree{ 29 int nxt[maxn][26]; 30 int fail[maxn]; 31 int cnt[maxn]; 32 int num[maxn]; 33 int len[maxn]; 34 int S[maxn]; 35 int lst,n,p; 36 int newnode(int l) { 37 For(i,0,25) nxt[p][i]=0; 38 cnt[p]=0; 39 num[p]=0; 40 len[p]=l; 41 return p++; 42 } 43 void init() { 44 p=0; 45 newnode(0);newnode(-1); 46 lst=0;n=0;S[n]=-1; 47 fail[0]=1; 48 } 49 int get_fail(int x) { 50 while(S[n-len[x]-1]!=S[n]) x=fail[x]; 51 return x; 52 } 53 int add(int c) { 54 S[++n]=c; 55 int cur=get_fail(lst); 56 if(!nxt[cur][c]) { 57 int now=newnode(len[cur]+2); 58 fail[now]=nxt[get_fail(fail[cur])][c]; 59 nxt[cur][c]=now; 60 num[now]=num[fail[now]]+1; 61 } 62 lst=nxt[cur][c]; 63 cnt[lst]++; 64 return len[lst]; 65 } 66 void count() { 67 Fore(i,p-1,0) cnt[fail[i]]+=cnt[i]; 68 } 69 }; 70 Pam_Tree pt; 71 72 void Debug(int *a,int l){ 73 cout<<"Debug-----!!!-_-!!----------"<<endl; 74 For(i,1,l) cout<<a[i]<<" "; 75 cout<<endl; 76 } 77 void Debug(ll *a,int l){ 78 cout<<"Debug-----!!!-_-!!----------"<<endl; 79 For(i,1,l) cout<<a[i]<<" "; 80 cout<<endl; 81 } 82 void Debug(double *a,int l){ 83 cout<<"Debug-----!!!-_-!!----------"<<endl; 84 For(i,1,l) cout<<a[i]<<" "; 85 cout<<endl; 86 } 87 void Debug(char *s){ 88 cout<<"Debug-----!!!-_-!!----------"<<endl; 89 cout<<s+1<<endl; 90 } 91 int dcmp(double x) { 92 if(fabs(x)<=eps) return 0; 93 return x<0?-1:1; 94 } 95 struct Point{ 96 ll x,y; 97 Point(ll x=0,ll y=0):x(x),y(y) {} 98 Point operator - (const Point &a)const { return Point(x-a.x,y-a.y); } 99 bool operator < (const Point &a)const { if(a.x==x) return y>a.y; return x<a.x; } 100 }; 101 ll Dot(Vector a,Vector b){ return a.x*b.x+a.y*b.y; } 102 ll Cross(Vector a,Vector b){ return a.x*b.y-a.y*b.x; } 103 double len(Vector a) { return sqrt(Dot(a,a)); } 104 struct node{ 105 ll x,id; 106 node(ll x=0,ll id=0):x(x),id(id) {} 107 bool operator < (const node &a)const { if(x==a.x) return id<a.id; return x>a.x; } 108 }; 109 struct Node{ 110 int l; 111 ll x; 112 bool operator < (const Node &a)const { 113 if(l==a.l) return x<a.x; 114 return l>a.l; 115 } 116 }; 117 ll quick_pow(ll a,ll b) { 118 ll base=1; 119 while(b) { 120 if(b&1) base=base*a%Mod; 121 a=a*a%Mod;b>>=1; 122 } 123 return base%Mod; 124 } 125 char s[maxn]; 126 int l,rt; 127 ll k; 128 Node ans[maxn]; 129 void solve() { 130 pt.init();rt=1; 131 cin>>l>>k; 132 scanf("%s",s+1); 133 For(i,1,l) pt.add(s[i]-'a'); 134 pt.count(); 135 For(i,2,pt.p-1){ 136 if(pt.len[i]%2 ) ans[rt].l=pt.len[i],ans[rt++].x=pt.cnt[i]; 137 } 138 sort(ans+1,ans+rt); 139 ll cur=1; 140 // For(i,1,rt-1) cout<<ans[i].l<<" "<<ans[i].x<<endl; 141 For(i,1,rt-1) { 142 if(k==0) break; 143 if(k<=ans[i].x) cur=(quick_pow(ans[i].l,k)%Mod*cur)%Mod,k=0; 144 else cur=(quick_pow(ans[i].l,ans[i].x)*cur%Mod)%Mod,k-=ans[i].x; 145 } 146 if(k) cout<<-1<<endl; 147 else cout<<cur%Mod<<endl; 148 } 149 int main() { 150 int tt=1; 151 while(tt--) solve(); 152 return 0; 153 }
HDU 5157 Harry and magic string
求不向交的回文子串的对数
直接将整个串正向插入,求每次插入时以该位置为右端点的回文子串有多少个,
再将整个串反向插入到回文树中,同样统计子串的个数,最后统计求和即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define eps 1e-9 4 #define For(i,a,b) for(int i=a;i<=b;i++) 5 #define Fore(i,a,b) for(int i=a;i>=b;i--) 6 #define lson l,mid,rt<<1 7 #define rson mid+1,r,rt<<1|1 8 #define mkp make_pair 9 #define pb push_back 10 #define sz size() 11 #define met(a,b) memset(a,b,sizeof(a)) 12 #define iossy ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) 13 #define fr freopen 14 #define pi acos(-1.0) 15 #define Vector Point 16 #define fir first 17 #define sec second 18 #define endl '\n' 19 typedef pair<int,int> pii; 20 const long long linf=1LL<<62; 21 const int iinf=1000000009; 22 const double dinf=1e15; 23 const int Mod=51123987; 24 typedef long long ll; 25 typedef long double ld; 26 const int maxn=200005; 27 const int MAXN=500005; 28 struct Pam_Tree{ 29 vector<pii >nxt[maxn]; 30 int fail[maxn]; 31 int cnt[maxn]; 32 int num[maxn]; 33 int len[maxn]; 34 int S[maxn]; 35 int lst,n,p,x; 36 int newnode(int l) { 37 nxt[p].clear(); 38 cnt[p]=0; 39 num[p]=0; 40 len[p]=l; 41 return p++; 42 } 43 void init() { 44 p=0; 45 newnode(0);newnode(-1); 46 lst=0;n=0;S[n]=-1; 47 fail[0]=1; 48 } 49 int find(int cur,int c){ 50 For(i,1,nxt[cur].sz) { 51 if(nxt[cur][i-1].fir==c) return nxt[cur][i-1].sec; 52 } 53 return 0; 54 } 55 int get_fail(int x) { 56 while(S[n-len[x]-1]!=S[n]) x=fail[x]; 57 return x; 58 } 59 int add(int c) { 60 S[++n]=c; 61 int cur=get_fail(lst); 62 x=find(cur,c); 63 if(!x) { 64 int now=newnode(len[cur]+2); 65 fail[now]=find(get_fail(fail[cur]),c); 66 nxt[cur].pb(mkp(c,now)); 67 num[now]=num[fail[now]]+1; 68 x=now; 69 } 70 lst=x; 71 cnt[lst]++; 72 return num[lst]; 73 } 74 ll count() { 75 Fore(i,p-1,0) cnt[fail[i]]+=cnt[i],cnt[fail[i]]%=Mod; 76 } 77 }; 78 Pam_Tree pt; 79 ll ans[maxn],ans2; 80 ll cnt1,cnt2,cnt; 81 char s[maxn]; 82 int n; 83 void solve() { 84 while(~scanf("%s",s+1)){ 85 pt.init();met(ans,0); 86 int l=strlen(s+1);cnt1=0;cnt2=0; 87 For(i,1,l) ans[i]=ans[i-1]+pt.add(s[i]-'a'); 88 cnt2=pt.count(); 89 pt.init(); 90 Fore(i,l,1) ans2=pt.add(s[i]-'a'),cnt1=cnt1+ans2*ans[i-1]; 91 cout<<cnt1<<endl; 92 } 93 } 94 int main() { 95 int tt=1; 96 while(tt--) solve(); 97 return 0; 98 }
题目大意:求相交的回文子串有多少对
直接考虑相交不好考虑,可以反着来,用回文子串的对数减去不相交的回文子串的数量即可,回文树搞搞就行。
题目内存要求较高,可以考虑用map或vector来存next数组
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define eps 1e-9 4 #define For(i,a,b) for(int i=a;i<=b;i++) 5 #define Fore(i,a,b) for(int i=a;i>=b;i--) 6 #define lson l,mid,rt<<1 7 #define rson mid+1,r,rt<<1|1 8 #define mkp make_pair 9 #define pb push_back 10 #define sz size() 11 #define met(a,b) memset(a,b,sizeof(a)) 12 #define iossy ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) 13 #define fr freopen 14 #define pi acos(-1.0) 15 #define Vector Point 16 #define fir first 17 #define sec second 18 #define endl '\n' 19 typedef pair<int,int> pii; 20 const long long linf=1LL<<62; 21 const int iinf=1000000009; 22 const double dinf=1e15; 23 const int Mod=51123987; 24 typedef long long ll; 25 typedef long double ld; 26 const int maxn=2000005; 27 const int MAXN=500005; 28 struct Pam_Tree{ 29 unordered_map<int,int>nxt[30]; 30 int fail[maxn]; 31 int cnt[maxn]; 32 int num[maxn]; 33 int len[maxn]; 34 int S[maxn]; 35 int lst,n,p; 36 int newnode(int l) { 37 cnt[p]=0; 38 num[p]=0; 39 len[p]=l; 40 return p++; 41 } 42 void init() { 43 p=0; 44 For(i,0,26) nxt[i].clear(); 45 newnode(0);newnode(-1); 46 lst=0;n=0;S[n]=-1; 47 fail[0]=1; 48 } 49 int get_fail(int x) { 50 while(S[n-len[x]-1]!=S[n]) x=fail[x]; 51 return x; 52 } 53 int add(int c) { 54 S[++n]=c; 55 int cur=get_fail(lst); 56 if(!nxt[c][cur]) { 57 int now=newnode(len[cur]+2); 58 fail[now]=nxt[c][get_fail(fail[cur])]; 59 nxt[c][cur]=now; 60 num[now]=num[fail[now]]+1; 61 } 62 lst=nxt[c][cur]; 63 cnt[lst]++; 64 return num[lst]; 65 } 66 ll count() { 67 ll res=0; 68 Fore(i,p-1,0) cnt[fail[i]]+=cnt[i],cnt[fail[i]]%=Mod; 69 Fore(i,p-1,2) res+=cnt[i],res%=Mod; 70 return res; 71 } 72 }; 73 Pam_Tree pt; 74 ll ans[maxn],ans2; 75 ll cnt1,cnt2,cnt; 76 char s[maxn]; 77 int n; 78 void solve() { 79 cin>>n; 80 pt.init(); 81 cin>>s+1;met(ans,0); 82 int l=strlen(s+1);cnt1=0;cnt2=0; 83 For(i,1,l) ans[i]=ans[i-1]+pt.add(s[i]-'a'),ans[i]%=Mod; 84 cnt2=pt.count(); 85 pt.init(); 86 Fore(i,l,1) ans2=pt.add(s[i]-'a'),cnt1=(cnt1+ans2*ans[i-1]%Mod)%Mod; 87 cout<<((cnt2*1LL*(cnt2-1)/2)%Mod-cnt1+Mod)%Mod<<endl; 88 } 89 int main() { 90 int tt=1; 91 while(tt--) solve(); 92 return 0; 93 }
HDU 4426 Palindromic Substring
将整个串插入回文树中,对于每个人,统计其所有回文子串的价值,排序,最后取第k个
因为k可能会超int,子串的数量也会超int,所以全用long long了
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define eps 1e-9 4 #define For(i,a,b) for(int i=a;i<=b;i++) 5 #define Fore(i,a,b) for(int i=a;i>=b;i--) 6 #define lson l,mid,rt<<1 7 #define rson mid+1,r,rt<<1|1 8 #define mkp make_pair 9 #define pb push_back 10 #define sz size() 11 #define met(a,b) memset(a,b,sizeof(a)) 12 #define iossy ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) 13 #define fr freopen 14 #define pi acos(-1.0) 15 #define Vector Point 16 #define fir first 17 #define sec second 18 #define endl '\n' 19 typedef pair<int,int> pii; 20 const long long linf=1LL<<62; 21 const int iinf=1000000009; 22 const double dinf=1e15; 23 const int Mod=777777777; 24 typedef long long ll; 25 typedef long double ld; 26 const int maxn=200005; 27 const int MAXN=500005; 28 struct Pam_Tree{ 29 int nxt[maxn][26]; 30 int fail[maxn]; 31 int cnt[maxn]; 32 int num[maxn]; 33 int len[maxn]; 34 int S[maxn]; 35 int lst,n,p,x; 36 int newnode(int l) { 37 For(i,0,25) nxt[p][i]=0; 38 cnt[p]=0; 39 num[p]=0; 40 len[p]=l; 41 return p++; 42 } 43 void init() { 44 p=0; 45 newnode(0);newnode(-1); 46 lst=0;n=0;S[n]=-1; 47 fail[0]=1; 48 } 49 int get_fail(int x) { 50 while(S[n-len[x]-1]!=S[n]) x=fail[x]; 51 return x; 52 } 53 int add(int c) { 54 S[++n]=c; 55 int cur=get_fail(lst); 56 if(!nxt[cur][c]) { 57 int now=newnode(len[cur]+2); 58 fail[now]=nxt[get_fail(fail[cur])][c]; 59 nxt[cur][c]=now; 60 num[now]=num[fail[now]]+1; 61 } 62 lst=nxt[cur][c]; 63 cnt[lst]++; 64 return num[lst]; 65 } 66 ll count() { 67 Fore(i,p-1,0) cnt[fail[i]]+=cnt[i],cnt[fail[i]]%=Mod; 68 } 69 }; 70 Pam_Tree pt; 71 int v[25][30]; 72 ll k[25],cnt; 73 ll f[200000],u,vv; 74 map<ll,ll>mp; 75 void dfs(int now,int x,ll st) { 76 if(now!=0 && now!=1) mp[st]+=pt.cnt[now]; 77 For(i,0,25) { 78 if(pt.nxt[now][i]){ 79 dfs(pt.nxt[now][i],x,(st+v[x][i]*1LL*f[(pt.len[now]+1)/2]%Mod)%Mod); 80 } 81 } 82 } 83 map<ll,ll>::iterator it; 84 int n,m; 85 char s[200005]; 86 void solve() { 87 pt.init(); 88 scanf("%d%d",&n,&m); 89 scanf("%s",s+1); 90 For(i,1,n) pt.add(s[i]-'a'); 91 pt.count(); 92 For(i,1,m) { 93 scanf("%lld",&k[i]); 94 For(j,0,25) 95 scanf("%d",&v[i][j]); 96 } 97 For(i,1,m) { 98 mp.clear(); 99 dfs(0,i,0);dfs(1,i,0);cnt=k[i]; 100 for(it=mp.begin();it!=mp.end();it++) { 101 u=(*it).first;vv=(*it).sec; 102 // cout<<u<<" "<<vv<<endl; 103 if(cnt-vv>0)cnt-=vv; 104 else { 105 cnt=0; 106 printf("%lld\n",u%Mod); 107 break; 108 } 109 } 110 } 111 } 112 int main() { 113 f[0]=1; 114 For(i,1,109900) f[i]=f[i-1]*26LL%Mod; 115 int tt=1; 116 cin>>tt; 117 while(tt--) solve(),cout<<endl; 118 return 0; 119 }