https://atcoder.jp/contests/abc295/tasks/abc295_d
好题,本来以为需要从区间问题上考虑,奈何算法世界无奇不有。
大意是求一个0-9的子串中区间内的所有元素是成双成对出现的,串的长度为5e5.
很明显我们可以前缀和维护然后去暴力n^2一下。但是数据不允许。
考虑状压每个位置的前缀关系,将状态计数,如果之后又遇到此状态,那么一定存在之前的所有状态的位置到现在位置是一个合法的区间。
本质上还是个思维问题。
code:
const int nn = 5e5+10; ll s[nn][10]; string st; map<string,int> mp; ll ans = 0; void work(int i){ for(int j=0;j<10;j++) st[j] = s[i][j]%2+'0'; ans+=mp[st]; mp[st]++; } void solve() { string str; cin>>str; str = "@"+str; int n = str.size()-1; st.resize(10); for(int i=0;i<10;i++) st[i] = '0'; mp[st]++; for(int i=1;i<=n;i++){ int t = str[i] - '0'; for(int j=0;j<10;j++){ s[i][j] = s[i-1][j]+(j==t); } work(i); } cout<<ans<<endl; }