首页 > 其他分享 >P5446

P5446

时间:2024-02-20 21:11:26浏览次数:28  
标签:int Manacher else vis P5446 回文

P5446

  • 由翻转可知:\(S[j, k] == S[k, i]\)

  • 因此 R 是 S 的前缀 且 R 的后缀是回文串

    • 用 Manacher 算出最大回文半径 d
  • 此外,R 也可以由多次反转得到

    • 条件是:
      • R' 经过反转后是符合R 是 S 的前缀 且 R 的后缀是回文串
      • 且 R' 本身是回文串,这使得 R' 翻转后得到 R
    # include <bits/stdc++.h>
    # define int long long
    using namespace std;
    const int N = (int)1e6 + 10;
    
    int t;
    int l, r, d[N];
    bool vis[N];
    char s[N];
    
    void Manacher(int n){
    	int l = 0, r = 0;
    	s[0] = '@', s[n + 1] = '#';	
    	for(int i = 1; i <= n; i++){
    		d[i] = 0;
    		if(i > r){
    			while(s[i + d[i]] == s[i - d[i]]){
    				d[i]++;
    			}
    			l = i - d[i] + 1;
    			r = i + d[i] - 1;
    		}else{
    			int j = l + (r - i);
    			if(j - d[j] >= l){
    				d[i] = d[j];
    			}else{
    				d[i] = r - i;
    				while(s[i + d[i]] == s[i - d[i]]){
    					d[i]++;
    				}				
    				l = i - d[i] + 1;
    				r = i + d[i] - 1;				
    			}
    		}
    	}
    	for(int i = 1; i <= n; i++){
    		d[i]--;
    	}
    }
    
    signed main(){
    //	freopen("1.in", "r", stdin);
    	cin >> t;
    	while(t--){
    		cin >> (s + 1);
    		
    		int n = strlen(s + 1);	
    		Manacher(n);
    		
    		for(int i = n; i >= 1; i--){
    			if(i + d[i] == n){
    				vis[i] = 1;
    			}else if(vis[i + d[i]] == 1 && i - d[i] == 1){
    				vis[i] = 1;
    			}
    		}
    		for(int i = 1; i <= n; i++){
    			if(vis[i] == 1){
    				cout << i << " ";
    			}
    			vis[i] = 0;
    		}
    		cout << "\n";
    	}
    }
    

标签:int,Manacher,else,vis,P5446,回文
From: https://www.cnblogs.com/wangyangjena/p/18024061

相关文章

  • Luogu P5446 [THUPC2018] 绿绿和串串
    根据题目能发现一个性质,设转化前的字符串为\(s\),转化后的字符串为\(s'\),则\(s'_{|s|}\)为\(s'\)的中心,即\(s'_{|s|}\)求出来的回文串左边界为\(1\)右边界为\(|s'|\)找出这个性质就挺简单了,考虑先对给出的\(S\)用\(\text{manacher}\)求出每个节点\(i\)对应的左边......
  • P5446 [THUPC2018]绿绿和串串 题解
    Description给定一个串\(S\),要求串\(S\)是串\(R\)经过多次翻转后的前缀。问有多少种初始长度的串\(R\)。串\(R\)翻转的定义是将前\(|R|-1\)个字符倒序排列后,插入到串的最后。如\(\mathrm{aaa}\)翻转后得到\(\mathrm{abcdcba}\)。Solution我们先设以\(i\)为......