萌萌思维题,但是考场差一点AC。
题目等价于寻找区间 \([l,r]\) 满足数字 \(0\)~\(9\) 各出现偶数次。
根据
找筷子
这道题的经验,出现偶数次 = 异或和为 \(0\) 。
但是发现如果和找筷子一样直接异或到一起会出现冲突
(例子:$3 \oplus 5 \oplus 6 = 0 $)。
所以变成二进制数就可以了。
朴素想法是暴力枚举每个区间,然后异或判断。复杂度 \(O(|S|^3)\),显然无法通过本题。
利用前缀和进行优化,可以把复杂度降到 \(O(|S|^2)\),仍然不能通过本题。
由于题目要求的只是数量,不需要求出每个区间。
考虑满足条件的 \([l,r]\) 区间性质,必满足 \(xorsum_{l-1} = xorsum_{r}\)。
那么求 \(xorsum\) 时记录当前值的出现次数 \(cnt_x\),以 \(r\) 为右端点,满足条件的 \(l\) 数量是 \(cnt_x - 1\),也就是区间数量。
累加即可。
code:
#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
#define LL long long
const int N=5e5+5;
int a[N],m[N];
int cnt;
LL ans;//不开long long见祖宗
int main()
{
while(char c=getchar()){
if(isdigit(c)) a[++cnt]=c-'0';
else break;
}
int x=0;
m[0]=1;//处理以1为左端点的情况
rep(i,cnt){
x^=(1<<a[i]);//状压
ans+=m[x];
m[x]++;
}
cout<<ans<<endl;
return 0;
}
标签:题解,复杂度,ABC295D,异或,区间,oplus,xorsum
From: https://www.cnblogs.com/Cindy-Li/p/18048092