Codeforces Round 855 (Div. 3) F. Dasha and Nightmares(题解 + 详细思考过程讲解)
创始人
2024-05-28 15:07:39
0

F. Dasha and Nightmares(二进制)

链接:F. Dasha and Nightmares

题目最重要的破题点思路 即第4点 由某银牌佬提供,唉膜拜大佬。

题意

给定 nnn 个字符串,(1<=n<=2∗105)(1 <=n<=2 * 10^5)(1<=n<=2∗105) 字符串长度之和不超过 5∗1065 *10^65∗106。
求字符串对si,sjsi,sjsi,sj个数,要满足以下条件
条件1.拼接后恰好有 252525 种字母。
条件2.拼接后每个字母个数为奇数。

题解 + 思考过程

1. 最开始想到用二进制,将每个字符串转化为一个长度为 262626 的二进制数,字符 chchch 的个数, 奇数 =1=1=1 ,偶数 =0=0=0
例如 str="a"str = "a"str="a" 二进制串 =1000……= 1000……=1000……, str="ab"=1100……str = "ab" = 1100……str="ab"=1100……, str="aab"=0100……str = "aab" = 0100……str="aab"=0100……
对于条件1:可以想到对于每个字符串枚举哪一个字符舍去。
对于条件2:用位运算直接去找到合法的,异或全 111 二进制数再减去应该舍去的字符位上的1。

2. 但是必须只有 252525 个,但是偶数对应 000, 那么不知道该字符是否有,因为没有该字符为 000 也对应 000。
例如枚举字符 aaa 没有, 但字符串 str="aa"str = "aa"str="aa" ,那么该字符串代表的二进制为全 000,就可以和 字符串 "b∼z""b\sim z""b∼z" 拼接 但拼接后有262626个字母,显然不合法。

3. 于是想到用三进制来表示,0=00 = 00=0, 奇数 =1= 1=1 大于 000 的偶数 =2= 2=2, 用字典树去计算
但是由于 111 对应 000 和 222 (字符串该位上为 111,那么该位上为 000 或 222 的都可以与之拼接)
这样递归时间复杂度可能达到 222 的幂次方级别。不可行。

4. 最后想到 枚举的不存在的那个字符,只有两个字符串都没有该字符才能拼接后满足。
所以我们可以每次遍历不存在 字符 chchch 的字符串集合,这样就不用考虑该位的 000 是大于 000 的偶数还是 000 的问题了。
因为除了我们枚举的该位必须不存在的其他字符 都必须为奇数,所以至少存在,对应拼接的是 000 还是大于 000 的偶数就无所谓了。
可以直接采取1.做法,不过需要在每次计算后清除贡献。(如果不清除,影响可以参考2.)。

代码

#include 
#include 
#include 
using namespace std;
#define ll long long
const int N = 2e5 + 10, M = 1 << 26;
const int K = (1 << 26) - 1;//长度为26的全1二进制数
string s[N];
int t[N], val[M];//t[i]:转化后二进制数 val[i]:计数
vectorg[26];//g[i]:没有字符i的字符串的下标
int main()
{ios::sync_with_stdio(false);cout.tie(NULL);int n;cin >> n;for(int i = 1; i <= n; i ++){cin >> s[i];int len = s[i].length();int vis[30] = {0};for(int j = 0; j < len; j ++){vis[s[i][j] - 'a'] ++;}int num = 0;for(int j = 0; j < 26; j ++){if(vis[j] & 1) num += (1 << j);if(!vis[j]) g[j].push_back(i);}t[i] = num;}ll ans = 0;for(int i = 0; i < 26; i ++){//枚举没有i字符的字符串,只有都没有某个字符的字符串才能匹配for(int id : g[i]){val[t[id]] ++;int v = t[id] ^ K ^ (1 << i);//能与si拼接的字符串所代表的二进制数ans += val[v];}for(int id : g[i]) val[t[id]] --;//清除贡献}cout << ans;return 0;
}

相关内容

热门资讯

中证A500ETF摩根(560... 8月22日,截止午间收盘,中证A500ETF摩根(560530)涨1.19%,报1.106元,成交额...
A500ETF易方达(1593... 8月22日,截止午间收盘,A500ETF易方达(159361)涨1.28%,报1.104元,成交额1...
何小鹏斥资约2.5亿港元增持小... 每经记者|孙磊    每经编辑|裴健如 8月21日晚间,小鹏汽车发布公告称,公司联...
中证500ETF基金(1593... 8月22日,截止午间收盘,中证500ETF基金(159337)涨0.94%,报1.509元,成交额2...
中证A500ETF华安(159... 8月22日,截止午间收盘,中证A500ETF华安(159359)涨1.15%,报1.139元,成交额...
科创AIETF(588790)... 8月22日,截止午间收盘,科创AIETF(588790)涨4.83%,报0.760元,成交额6.98...
创业板50ETF嘉实(1593... 8月22日,截止午间收盘,创业板50ETF嘉实(159373)涨2.61%,报1.296元,成交额1...
港股异动丨航空股大幅走低 中国... 港股航空股大幅下跌,其中,中国国航跌近7%表现最弱,中国东方航空跌近5%,中国南方航空跌超3%,美兰...
电网设备ETF(159326)... 8月22日,截止午间收盘,电网设备ETF(159326)跌0.25%,报1.198元,成交额409....
红利ETF国企(530880)... 8月22日,截止午间收盘,红利ETF国企(530880)跌0.67%,报1.034元,成交额29.0...