回文树练习 Part1

  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 }
View Code

  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 }
View Code

  HYSBZ - 3676  回文串

  回文树水题

  
  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 }
View Code

  HYSBZ - 2565 最长双回文串

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

  
  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 }
View Code

  HYSBZ - 2160 拉拉队排练

  回文树插入后统计长度回文子串的长度和数量,排序后直接求前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 }
View Code

  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 }
View Code

  CodeForces 17E

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

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

  题目内存要求较高,可以考虑用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 }
View Code

   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 }
View Code

猜你喜欢

转载自www.cnblogs.com/cjbiantai/p/9816944.html