zoukankan      html  css  js  c++  java
  • EZOJ #387字符串

    分析

    似乎ttl的模拟赛t3总是折半搜索?

    先把所有串转化为每个字母的0/1状态

    之后我们将所有字符串分为两半

    分别枚举状态

    我们发现只有左右两边的字母状态相等才能保证这个集合合法

    所以我们在搜左半边的时候每次加入一个pair

    表示异或值为x用了y个数

    搜完后先将它排序

    然后搜右边的时候每次lower_bound一下即可

    似乎ttl的数据比较强我的代码常数又很大,所以要开O2才能过/kk

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define fi first
    #define se second
    #define mp make_pair
    #define pi pair<int,int>
    #define int long long
    pi a[(1<<20)+5];
    int ans,wh[110],n,m,sum[30],cnt1,mx;
    char s[11000];
    inline void dfs1(int p,int lim,int now,int tot){
        if(p>lim){
          a[++cnt1]=mp(now,tot);
          return;
        }
        dfs1(p+1,lim,now^wh[p],tot+1);
        dfs1(p+1,lim,now,tot);
        return;
    }
    inline void dfs2(int p,int lim,int now,int tot){
        if(p>lim){
          pi *le=lower_bound(a+1,a+cnt1+1,mp(now,-1ll));
          pi *ri=lower_bound(a+1,a+cnt1+1,mp(now+1,-1ll));
          ans+=(ri-le);
          ri--;
          if((ri->fi)==now)mx=max(mx,(ri->se)+tot);
          return;
        }
        dfs2(p+1,lim,now^wh[p],tot+1);
        dfs2(p+1,lim,now,tot);
        return;
    }
    signed main(){
        int i,j,k;
        scanf("%lld",&n);
        for(i=1;i<=n;i++){
          memset(sum,0,sizeof(sum));
          scanf("%s",s);
          m=strlen(s);
          for(j=0;j<m;j++)sum[s[j]-'a']^=1;
          for(j=0;j<26;j++)
            wh[i]|=((1<<j)*sum[j]);
        }
        dfs1(1,n/2,0,0);
        sort(a+1,a+cnt1+1);
        dfs2(n/2+1,n,0,0);
        printf("%lld %lld
    ",ans-1ll,mx);
        return 0;
    }
  • 相关阅读:
    二分查找binarySearch
    快速排序quicksort实现方法
    读书清单
    windows 下遍历文件夹
    如何输出 android.mk 及 Application.mk 中个变量的值
    【转】 armeabi与armeabi-v7a
    Application.mk
    【转】TypeError: 'module' object is not callable 原因分析
    User breakpoint called from code at XXX的解决方式记录
    关于溢出的一些体会
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/11520518.html
Copyright © 2011-2022 走看看