• 最小线段覆盖 C神奇项链


    母亲节就要到了,小 H 准备送给她一个特殊的项链。
    这个项链可以看作一个用小写字母组成的字符串,每个小写字母表示一种颜色。

    为了制作这个项链,小 H 购买了两个机器。
    第一个机器可以生成所有形式的回文串,第二个机器可以把两个回文串连接起来,而且第二个机器还有一个特殊的性质:
       假如一个字符串的后缀和一个字符串的前缀是完全相同的,那么可以将这个重复部分重叠。例如:aba和aca连接起来,可以生成串abaaca或 abaca。

    现在给出目标项链的样式,询问你需要使用第二个机器多少次才能生成这个特殊的项链。

    最小线段覆盖 ... 

    我想的是树状数组 区间差分修改 ... 

    没有Hack 自己 ai...

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    #define rel(i,x,y) for(ll i=(x);i<(y);i++)
    #define rep(i,x,y) for(ll i=(x);i<=(y);i++)
    #define red(i,x,y) for(ll i=(x);i>=(y);i--)
    #define res(i,x) for(ll i=head[x];i;i=nxt[i])
    using namespace std;
    
    const ll N=1e5+5;
    const ll Inf=1e18;
    
    inline ll read() {
        ll x=0;char ch=getchar();bool f=0;
        while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return f?-x:x;
    }
    int R[120000];
    char s[120000],S[120000];
    struct node
    {
    
        int x,y;
    
    }a[120000];
    int cnt=0;
    int n;
    int tot;
    void init()
    {
         tot=1;
        S[0]='@';
        S[1]='#';
        for(int i=1;i<=n;i++)
    {
        S[++tot]=s[i];
        S[++tot]='#';
    }
        S[++tot]='';
    
    }
    void mlc()
    {
    
        int p=0;
        int maxlen=0;
        for(int i=1;i<tot;i++)
        {
            if(i<maxlen) R[i]=min(R[2*p-i],maxlen-i+1);
            else
            R[i]=1;
            while(S[i+R[i]]==S[i-R[i]]) R[i]++;
        
            {        
                a[++cnt].x=i-R[i]+1;
                a[cnt].y=i+R[i]-1;
            }
                if(i+R[i]-1>maxlen)
            {
                    maxlen=i+R[i]-1;
                    p=i;
            
            }
        }        
    }
    
    bool cmp(node aa,node b)
    {
        if(aa.x==b.x)
        return aa.y>b.y;
        else
        return aa.x<b.x;
    
    }
    int main() {
    
        while(scanf("%s",s+1)!=EOF)
    {
        
        for(int i=0;i<=n;i++)
    {
        R[i]=0;
    
    }
        n=strlen(s+1);
        cnt=0;
        int ans=0;
        init();
        mlc();
        sort(a+1,a+1+cnt,cmp);
        int l=a[1].y;
        int now=l;
        int j;
        int fla=0;int tes=0;
        if(a[1].y>=a[cnt].y) 
        {
            cout<<0;
            continue;
    
        }
        for(int i=2;i<=cnt;i++)
        {
            l=now;
            
                while(a[i].x<=l&&i<=cnt)
    {
                
                now=max(now,a[i].y);i++;
    
    }
        i--;
        if(now==l) break;
        else ans++;
    
    
    
    }    cout<<ans<<endl;
    
    }
    }
    刀剑映出了战士的心。而我的心,漆黑且残破
  • 相关阅读:
    设计模式之观察者模式
    设计模式之外观模式
    设计模式之模板模式
    设计模式之装饰器模式
    设计模式之代理模式
    .NET常见问题汇总
    使用位运算计算两个整数的加减
    一个程序判断CPU是大端还是小端
    后缀表达式 转 表达式树
    实习一个月的小结
  • 原文地址:https://www.cnblogs.com/OIEREDSION/p/11349852.html
Copyright © 2020-2023  润新知