CF1800F Dasha and Nightmares

F.Dasha and Nightmares#

题意:n 个字符串 si,问有多少对不同的 (i,j) (1ijn),使得 sisj​ 拼接后的字符串满足下列条件:

  • 长度为奇数
  • 恰好出现 25 个字母
  • 每个字母出现次数为奇数

显然,如果满足后两个条件,第一个条件也满足。
由于只与是否出现和出现次数有关,不妨用两个数 ai,bi 代替 si
a 表示出现过哪些字符,b 表示出现过哪些次数为奇的字符。

    for(char c : s) {
        a[i] |= 1 << c - 'a';
        b[i] ^= 1 << c - 'a';
	}

如果 i,j 满足条件,则

  • a[i] | a[j] 恰好 25 位。
  • a[i] | a[j] = b[i] ^ b[j]

枚举没出现的那一位 k,则

  • a[i] >> k & 1 = 0
  • a[j] >> k & 1 = 0
  • a[i] | a[j] = b[i] ^ b[j] = ((1 << 26) - 1) ^ (1 << k)

val = ((1 << 26) - 1) ^ (1 << k)
一个第 k 位为 0 的 a[i] 对答案的贡献是满足以下条件的 j 的个数

  • a[j] >> k & 1 = 0
  • b[j] = val ^ b[i]

用哈希表或者桶记录先前 b 出现的次数即可。

	rep(k, 0, 25) {
		int val = ((1 << 26) - 1) ^ 1 << k;
		vector<int> t;
		rep(i, 1, n) {
			if(a[i] >> k & 1 ^ 1) {
				++ cnt[b[i]];
				t.pb(b[i]);
			}
		}
		for(int x : t) ans += cnt[val ^ x];
		for(int x : t) cnt[x] = 0;
	}

我这里由于 i,j 是无序的,所以最终答案除二(自己和自己一定不行)。

posted @   Lu_xZ  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示