hdu 5229 ZCC loves strings && BestCoder Round #41 1002

ZCC有N个字符串,他正在和Miss G.用这N个字符串玩一个小游戏。ZCC会从这N个串中等概率随机选两个字符串(不可以是同一个)。然后,ZCC和Miss G.轮流操作。Miss G.总是先操作的。在每轮中,操作者可以选择操作A或操作B。

操作A:在两个串中选择一个当前非空的串,然后在这个串的末尾删去一个字符。

操作B: 若当前两个串完全相同且非空,则可以使用这个操作。此时两个串都被清空。

不能操作的玩家输掉了这个游戏。

ZCC想要知道他输掉游戏的概率是多少(也就是Miss G.获胜的概率)。
输入描述
第一行有一个整数
  
  
   
   T(T5)
  
  ,代表测试数据组数。
对于每组数据,第一行有一个非负整数
  
  
   
   N(2N20000)
  
  。接下来的N行中,每行有一个仅由小写字母构成的字符串。保证一组数据中字符串的总长度不超过
  
  
   
   200000
  
  .
输出描述
对于每组数据,输出单独的一行代表答案。答案用既约分数"p/q"的形式表示。如果答案是1,输出"1/1";如果答案是0,输出"0/1".
输入样例
1
3
xllendone
xllendthree
xllendfour
输出样例
2/3


#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long LL;
#define MAXN 200005
char s[MAXN];
struct Trie
{
    int ch[MAXN << 1][26],val[MAXN << 1];
    int cnt;
    void init()
    {
        cnt = 1;
        memset(ch[0],0,sizeof(ch[0]));
    }
    int insert(char * s)
    {
        int u = 0 , len = strlen(s);
        for(int i = 0;i < len;i++)
        {
            if(!ch[u][s[i] - 'a'])
            {
                memset(ch[cnt],0,sizeof(ch[cnt]));
                val[cnt] = 0;
                ch[u][s[i] - 'a'] = cnt++;
            }
            u = ch[u][s[i] - 'a'];
        }
        return val[u]++;
    }
}trie;
LL gcd(LL a,LL b)
{
    if(b)return gcd(b,a % b);
    else return a;
}
int main()
{
    int _,n;
    scanf("%d",&_);
    while(_--)
    {
        scanf("%d",&n);
        LL ans = 0;
        trie.init();
        int odd = 0,even = 0;
        for(int i = 0;i < n;i++)
        {
            scanf("%s",s);
            int cnt = trie.insert(s);
            int len = strlen(s);
            if(len & 1)
            {
                ans += even;
                odd++;
            }
            else
            {
                ans += odd;
                even++;
            }
            ans += cnt;
        }
        LL cur = n * (n - 1) / 2;
        if(ans == 0)puts("0/1");
        else printf("%I64d/%I64d\n",ans / gcd(ans,cur),cur / gcd(ans,cur));
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值