社区讨论

n^2logn做法,期望得分48,AC1~9 32pts求调

P7114[NOIP2020] 字符串匹配参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mhz4fh3n
此快照首次捕获于
2025/11/15 01:17
4 个月前
此快照最后确认于
2025/11/16 13:56
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
#define int __int128
#define PII pair<int,int>
#define fir first
#define sec second
#define pc putchar
using namespace std;
namespace IO{
	inline int rd(){
		int x=0,f=1;
		char c=getchar();
		while(c<'0'||c>'9'){
			if(c=='-'){
				f=-1;
			}
			c=getchar();
		}
		while(c>='0'&&c<='9'){
			x=(x<<1)+(x<<3)+(c^48);
			c=getchar();
		}
		return x*f;
	}
	inline void wt(int x){
		if(x<0){
			x=-x;
			pc('-');
		}
		if(x>9){
			wt(x/10);
			pc(x%10+'0');
		}
		else{
			pc(x+'0');
		}
		return ;
	}
}
using namespace IO;
namespace Main{
    int T;
    string s;
    int sum,res;
    int cnt[37];
    set<tuple<string, string, string>> st;
    inline int rend(string &str, int st, int len1, int len2){
        for(int k=0;;k++){
            int start=st+k*len2, end=st+(k+1)*len2-1;
            if(end>=len1){
            	return k+1;
			}
            for(int i=start;i<=end;i++){
                if(str[i-start]!=s[i]){
                	return k+1;
				}
            }
        }
    }
    inline int calc(int ed, int c, int ret, int edt){
        if(!ed || ed==s.size()-1){
        	return 0;
		}
        int cant=0, acnt[37]={};
        for(int i=0;i<ed;i++){
            ++acnt[s[i]-'a'];
            cant += (acnt[s[i]-'a']&1) ? 1 : -1;
            if(cant<=c){
                string A="",B="",C="";
				for(int q=0;q<=i;q++){
					A+=s[q];
				}
				for(int q=i+1;q<=ed;q++){
					B+=s[q];
				}
				for(int q=edt;q<s.size();q++){
					C+=s[q];
				}
				if(!C.size()){
					continue;
				}
                auto p = make_tuple(A, B, C);
                if(st.find(p) == st.end()){
                    ++ret;
                    st.insert(p);
                }
            }
        }
        return ret;
    }
    inline void dfs(string &str){
        int len=str.size();
        string sstr="";
        for(int i=0;i<len;i++){
            sstr+=str[i];
            int t=rend(sstr, i+1, len, i+1);
            for(int k=1;k<=t;k++){
                int stt=k*(i+1);
                int sum=0;
                int ccnt[37]={};
                for(int j=stt;j<len;j++){
                    ++ccnt[s[j]-'a'];
                    sum += (ccnt[s[j]-'a']&1) ? 1 : -1;
                }
                res += calc(i, sum, 0, stt);
            }
        }
        return ;
    }
    inline void main(){
        T=rd();
        while(T--){
            cin>>s;
            res=0;
            st.clear();
            dfs(s);
            wt(res), pc('\n');
        }
        return ;
    }
}
signed main(){
    Main::main();
    return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...