P4065 [JXOI2017]颜色

题面

  • get到一种 hash 乱搞。

  • 考虑题目要求如何在 hash 值中得以体现。

  • 为每个数赋上一个 hash 值,使得同一类数的 hash 值为零。

  • 那么满足要求的序列的 hash 值之和一定为零。

 1 #include<bits/stdc++.h>
 2 #define ll unsigned long long
 3 using namespace std;
 4 int t,n,x,tot;
 5 int    head[300050];
 6 int nex[300050];
 7 int ver[300050];
 8 ll s[300050];
 9 ll ans,tmp;
10 void add(int x,int y)
11 {
12     nex[++tot]=head[x];
13     ver[tot]=y;
14     head[x]=tot;
15 }
16 ll randm()
17 {
18     ll cnt=rand()*rand();
19     if(rand()&1)    return cnt;
20     else    return -cnt;
21 }
22 int main()
23 {
24     srand(time(0));
25     scanf("%d",&t);
26     while(t--)
27     {
28         scanf("%d",&n);tot=0;
29         memset(head,0,sizeof(head));
30         for(int i=1;i<=n;++i)
31         {
32             scanf("%d",&x);
33             add(x,i);
34         }
35         for(int i=1;i<=n;++i)
36         {
37             tmp=0;
38             for(int j=nex[head[i]];j;j=nex[j])
39             {
40                 s[ver[j]]=randm();
41                 tmp-=s[ver[j]];
42             }
43             s[ver[head[i]]]=tmp;
44         }
45         s[0]=0;ans=0;
46         for(int i=1;i<=n;++i)
47             s[i]+=s[i-1];
48         sort(s,s+n+1);
49         for(int i=0,j=0;i<=n;++j,i=j)
50         {
51             while(s[j+1]==s[i]&&j<n)
52                 ++j;
53             ans+=(ll)(j-i)*(j-i+1)/2;
54         }
55         printf("%lld\n",ans);
56     }
57     return 0;
58 }
hash 乱搞

转载于:https://www.cnblogs.com/wyher/p/10384349.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值