zoukankan      html  css  js  c++  java
  • BZOJ4936:match (不错的分治)

    给你一个由小写字母组成的字符串s,要你构造一个字典序最小的(认为左括号的字典序比右括号小)合法的括号
    序列与这个字符串匹配,字符串和括号序列匹配定义为:首先长度必须相等,其次对于一对匹配的左括号和右括号
    i,j,必须有s[i]==s[j]
    无解输出-1
    Input
     一行一个字符串s
    
    2<=n<=100000
    Output
     一行一个括号序列或者-1
    
    Sample Input
    abbaaa
    Sample Output
    (()())
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=100010;
    int num[26],used[26];
    char c[maxn],ans[maxn];
    int main()
    {
        int L,i;
        scanf("%s",c+1);
        L=strlen(c+1);
        for(i=1;i<=L;i++) num[c[i]-'a']++;
        for(i=0;i<26;i++){
            if(num[i]%2==1) {
                puts("-1");
                return 0;
            }
        }
        for(i=1;i<=L;i++){
            if(used[c[i]-'a']<num[c[i]-'a']/2) ans[i]='(';
            else ans[i]=')';
            used[c[i]-'a']++;
        }
        for(i=1;i<=L;i++) putchar(ans[i]);
        return 0;
    }
    View Code

    一开始交了发贪心,WA了,才想起来贪心的话,会导致匹配的时候不一定满足s[i]==s[j]    尴尬==

     然后看别人说是分治。 

    分治: 每次按照栈的合法性(用hash记录),对于[L,R],找到最远匹配的地方pos,使得char[L]==char[pos],且[L+1,pos-1],[pos+1,R]分别匹配。然后再以大化小解决小区间。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int maxn=200010;
    const int seed=131;
    const int Mod=1e9+7;
    map<int,int>Laxt[26];
    char c[maxn],ans[maxn]; 
    int Next[maxn],q[maxn],top,hash[maxn],fac[maxn];
    void solve(int L,int R)
    {
        if(L>=R) return ;
        int pos=Laxt[c[L]-'a'][hash[L-1]];
        while(ans[pos]=='('||ans[pos]==')') pos=Next[pos];//没加这一句TLE了很多次,why
        Laxt[c[L]-'a'][hash[L-1]]=Next[pos];
        ans[L]='('; ans[pos]=')';
        solve(pos+1,R); 
        solve(L+1,pos-1);
    }
    int main()
    {
        int N,i,j,now=0;
        scanf("%s",c+1);
        N=strlen(c+1);
        fac[0]=1; for(i=1;i<=N;i++) fac[i]=(ll)fac[i-1]*seed%Mod;
        for(i=1;i<=N;i++){ //hash里面,最高位才可以用来加减。 
            if(top&&c[q[top]]==c[i]){
               ((now-=(ll)fac[top-1]*(c[i]-'a'+1)%Mod))%=Mod,--top;
               if(now<0) now+=Mod; 
            } 
            else (now+=(ll)(c[i]-'a'+1)*fac[top]%Mod)%=Mod,q[++top]=i;
            hash[i]=now;
        }
        for(i=1;i<=N;i++){
            Next[i]=Laxt[c[i]-'a'][hash[i]];
            Laxt[c[i]-'a'][hash[i]]=i;
        }
        if(top!=0) { puts("-1"); return 0;}
        solve(1,N);
        for(i=1;i<=N;i++) putchar(ans[i]);
        return 0;
    }
  • 相关阅读:
    6大开源SIEM工具,安全信息和事件管理的“利器”
    数据库为何需要安全审计系统
    WEB漏洞扫描的开源工具
    12种开源Web安全扫描程序
    开源框架openresty+nginx 实现web应用防火墙(WAF)
    锦衣盾:开源WEB应用防火墙介绍
    20步打造最安全的Nginx Web服务器
    MySQL数据库审计系统
    数据库(分库分表)中间件对比
    Mysql调优基础、Mysql问题排查、Mysql优化、与hikari数据库连接池配合
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9165625.html
Copyright © 2011-2022 走看看