多校聯合集訓 A. 字串“水”題 (狀壓+雜湊)__常用技巧

來源:互聯網
上載者:User
題目描述

給出一個長度為 n 的字串(1<=n<=100000),求有多少個連續字串中所有的字母都出現了偶數次。


輸入

第一行一個正整數 T,表示資料群組數(1 <= T <= 10)。

接下來 T 行,每行有一個只包含小寫字母的字串。


輸出

每個答案輸出滿足要求字串個數。每個答案佔一行。


範例輸入

3aaabbccabcabc


範例輸出

061


思路

某位學長寫的題解,感覺挺詳細的,所以轉過來了。

從左至右掃一遍字串,利用狀態壓縮記錄下截止到當前位置各字母是奇數還是偶數,若奇數,則為 1 ,否則為 0 。

試想,如果掃一個字串時,截止到某種狀態所有個數為奇數的字母與截止到之前某種狀態所有個數為奇數的字母完全相同,則這兩個狀態之間的子串所有的字母一定都是出現了偶數次。(奇-奇=偶)

因為奇數用1表示,且所有個數為奇數的字母相同,(eg: 00010000000100000001000001 與 00010000000100000001000001 ),那麼這兩個狀態壓縮之後一定相同。

如果掃到的狀態之前出現過,則 ans+=該狀態之前出現過的狀態數 。


eg: ababab ,掃到第一個字母 a 時,狀態為 1 ( 00000000000000000000000001 ),當掃到第 5 個字母 a 時,狀態又為 1 ,則兩狀態之間的字母一定都是出現了偶數次。

對於狀態為 0 的情況,即截止到目前狀態,所有字母都出現了偶數次,則其與最初始(尚未開始掃字串)的狀態相同,可與最初始的狀態構成符合要求的連續子串,所以 status[0]=1 。


eg: abababab ,掃到第四個字母,狀態為 0 , ans+=status[0] ,然後 ans=1 。截止到第四個字母的子串與截止到第 0 個字母的子串形成的連續子串,即 abab ,所有的字母都出現了偶數次。 ++status[0] (狀態為 0 的狀態數又多了一個,應加 1 )。

掃到第八個字母,狀態為 0 , ans+=status[0] ,然後 ans=3 。截止到第八個字母的子串分別與截止到第 0 個字母的子串和截止到第四個字母的子串 形成的連續子串,即 abab ,所有的字母都出現了偶數次。

PS: status 開數組的話大約 6000 多萬,清空會逾時,因此改用 map 。

PS: 比賽開始的時候這道題直接用 map 是可以過的,不過後來資料加強了,應該也沒有重判,所以原來的代碼提交都會逾時。

解決的辦法是利用雜湊來縮短每次尋找的時間,之前學長們的做法都是打算用雜湊鏈來處理的,不過我想到了用 map 數組處理。(突然想到了一個很好用並且很好寫的解決雜湊衝突的方法,感覺好開心~)


AC 代碼

#include <stdio.h>#include <math.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <sstream>#include <algorithm>#include <set>#include <queue>#include <stack>#include <map>#include <bitset>#define maxn 100007using namespace std;typedef long long LL;char str[110000];map<int,int>sk[maxn];void solve(){    memset(sk,0,sizeof(sk));    for(int i=0; i<maxn; i++)        sk[i].clear();    int len=strlen(str);    int ret=0;    LL ans=0;    sk[0][0]=1;    for(int i=0; i<len; i++)    {        int now=str[i]-'a';        ret^=(1<<now);        ans+=sk[ret%maxn][ret];        sk[ret%maxn][ret]++;    }    cout<<ans<<endl;}int main(){    int T;    cin>>T;    while(T--)    {        cin>>str;        solve();    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.