HDU6038-Function-数学+思维-2017多校Team01

学长讲座讲过的,代码也讲过了,然而,当时上课没来听,听代码的时候也一脸o((⊙﹏⊙))o

我的妈呀,语文不好是硬伤,看题意看了好久好久好久(死一死)。。。

数学+思维题,代码懂了,也能写出来,但是还是有一点不懂,明天继续。

感谢我的队友不嫌弃我是他的猪队友(可能他心里已经骂了无数次我是猪队友了_(:з」∠)_ )

Function

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2021    Accepted Submission(s): 956

Problem Description

You are given a permutation a from 0 to n?1 and a permutation b from 0 to m?1.

Define that the domain of function f is the set of integers from 0 to n?1, and the range of it is the set of integers from 0 to m?1.

Please calculate the quantity of different functions f satisfying that f(i)=bf(ai) for each i from 0 to n?1.

Two functions are different if and only if there exists at least one integer from 0 to n?1 mapped into different integers in these two functions.

The answer may be too large, so please output it in modulo 109+7.

Input

The input contains multiple test cases.

For each case:

The first line contains two numbers n, m. (1≤n≤100000,1≤m≤100000)

The second line contains n numbers, ranged from 0 to n?1, the i-th number of which represents ai?1.

The third line contains m numbers, ranged from 0 to m?1, the i-th number of which represents bi?1.

It is guaranteed that ∑n≤106, ∑m≤106.

Output

For each test case, output "Case #x: y" in one line (without quotes), where x indicates the case number starting from 1 and y denotes the answer of corresponding case.

Sample Input

3 2

1 0 2

0 1

3 4

2 0 1

0 2 3 1

Sample Output

Case #1: 4

Case #2: 4

Source

2017 Multi-University Training Contest - Team 1

题意:吐槽啊,看不懂题意,后来推出来了,就是满足f(i)=bf(ai)这个式子。

函数套函数,假设a这个数组有5个数,那么就是f(0),f(1),f(2),f(3),f(4)这5个。

然后就是推。。。

对于f(0),i为0,i为a的下标,那么就是ai为a0,就是f(0)==bf(a0),然后看看a0对应的值是多少,这个值就是b的下标。就是这个意思。

然后就是,f这个函数值域是b数组中的任意一个数。假设a0对应的值是3,那么就是f(0)==bf(3)

f(3)的值是多少呢?就从b的数组中任选一个,如果这个数能够依次往下推,推到和最初的值相等就是符合条件的。推的这个过程就是一个循环节。

通过总结就可以发现,i和a数组有关,i和b数组也有关(和b有关的i不是和a有关的i),通过分别找出来a和b的循环节,就可以把个数相乘就是结果。

但是发现找循环节的时候,必须是b的循环节的长度是a的循环节的长度的约数才可以(就是b的长度这个数可以被a的长度的数整除)。

但是我这里还不太懂为什么可以,队友给我讲的,明天继续研究,先写完题解滚去补作业。。。

代码直接看我队友的代码吧,我也是看的他的写的。传送门:_(:з」∠)_

然后贴一下余学长的代码_(:з」∠)_ (别打我。。。)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<string>
 5 #include<queue>
 6 #include<algorithm>
 7 #include<stack>
 8 #include<cstring>
 9 #include<vector>
10 #include<list>
11 #include<bitset>
12 #include<set>
13 #include<map>
14 #include<time.h>
15 using namespace std;
16 typedef long long ll;
17 const int maxn=100000+10;
18 const int mod=1e9+7;
19 map<int,int>mp1,mp2;
20 map<int,int>::iterator it1,it2;
21 int a[maxn],b[maxn],vis[maxn];
22 int n,m;
23 void solve(int n,int *f,map<int,int> &mp)
24 {
25     memset(vis,0,sizeof(vis));
26     int j,k;
27     for(int i=0;i<n;i++)
28     {
29         j=i,k=0;
30         while(!vis[j])
31         {
32             k++;
33             vis[j]=1;
34             j=f[j];
35         }
36         if(k)
37         mp[k]++;
38     }
39 }
40 int main()
41 {
42     int kase=0;
43     while(scanf("%d%d",&n,&m)!=EOF)
44     {
45         for(int i=0;i<n;i++)
46         scanf("%d",&a[i]);
47         for(int i=0;i<m;i++)
48         scanf("%d",&b[i]);
49         mp1.clear();
50         mp2.clear();
51         solve(n,a,mp1);
52         solve(m,b,mp2);
53         ll ans=1;
54         for(it1=mp1.begin();it1!=mp1.end();it1++)
55         {
56             ll cnt=0,x=it1->first,t=it1->second;
57             for(it2=mp2.begin();it2!=mp2.end();it2++)
58             {
59                 int y=it2->first,num=it2->second;
60                 if(x%y==0)cnt=(cnt+y*num)%mod;
61             }
62             for(int i=1;i<=t;i++)
63             ans=(ans*cnt)%mod;
64         }
65         printf("Case #%d: %lld\n",++kase,ans);
66     }
67     return 0;
68 }

学长的代码比我队友的快_(:з」∠)_

溜了溜了。不想喝拿铁咖啡。

加油加油_(:з」∠)_

时间: 2024-08-28 12:19:01

HDU6038-Function-数学+思维-2017多校Team01的相关文章

hdu6035[dfs+思维] 2017多校1

/*hdu6035[dfs+思维] 2017多校1*/ //合并色块, 妙啊妙啊 #include<bits/stdc++.h> using namespace std; const double eps=1e-8; const int inf=0x3f3f3f3f; typedef long long LL; vector<int>G[200005]; LL sum[200005]; int c[200005],son[200005],mark[200005]; int n,u,

hdu6074[并查集+LCA+思维] 2017多校4

看了标答感觉思路清晰了许多,用并查集来维护全联通块的点数和边权和. 用另一个up[]数组(也是并查集)来保证每条边不会被重复附权值,这样我们只要将询问按权值从小到大排序,一定能的到最小的边权和与联通块中的点数. 下面是过程分析.过程中一共运用了两个并查集. [数据]110 31 21 32 42 53 63 74 85 95 109 6 3 1 501 4 2 5 209 10 8 10 40[分析]首先我们将图构建出来我们将m次询问按权值从小到大排序后: 1 4 2 5 209 10 8 10

hdu6059[字典树+思维] 2017多校3

#include <bits/stdc++.h> using namespace std; typedef long long LL; int trie[31 * 500005][2]; int no[31 * 500005]; int sz[31 * 500005]; int sum[31][2]; int T, n, temp, tot = 0; LL ans = 0; void solve(int x) { int now = 0; for (int i = 29; ~i; i--) {

hdu6069[素数筛法] 2017多校3

/*hdu6069[素数筛法] 2017多校3*/ #include <bits/stdc++.h> using namespace std; typedef long long LL; LL l, r, k; const LL MOD = 998244353LL; int T, n, prime[1100000], primesize; bool isprime[11000000]; void getlist(int listsize) { memset(isprime, 1, sizeof

程序设计中的数学思维函数总结(代码以C#为例)

最近以C#为例,学习了程序设计基础,其中涉及到一些数学思维,我们可以巧妙的将这些逻辑问题转换为代码,交给计算机运算. 现将经常会使用到的基础函数做一总结,供大家分享.自己备用. 1.判断一个数是否为奇数 定义:整数中,能被2整除的数是偶数,不能被2整除的数是奇数 思路点:n%2!=0则为奇数 /// <summary> /// 判断一个整数是不是奇数 /// </summary> /// <param name="n">要判断的整数</para

hdu6034[模拟] 2017多校1

/*hdu6034[模拟] 2017多校1*/ //暴力模拟26个26进制数即可, 要注意进位 #include<bits/stdc++.h> using namespace std; typedef long long LL; const double eps=1e-8; const int inf=0x3f3f3f3f; struct node{ char num[100005]; int ch,high; }bits[30]; const int mod=1000000007; int

hdu 4710 Balls Rearrangement (数学思维)

题意:就是  把编号从0-n的小球对应放进i%a编号的盒子里,然后又买了新盒子, 现在总共有b个盒子,Bob想把球装进i%b编号的盒子里.求重置的最小花费. 每次移动的花费为y - x ,即移动前后盒子编号的差值的绝对值. 算法: 题目就是要求                  先判断  n与  lcm(a,b)的大小,每一个周期存在循环,这样把区间缩短避免重复计算. 如果n>lcm(a,b)则   ans = (n/lcm)*solve(lcm)+solve(n%lcm) 否则   ans =

Acdreamoj1115(数学思维题)

题意:1,3是完美数,如果a,b是完美数,则2+a*b+2*a+2*b,判断给出的n是否是完美数. 解法:开始只看出来2+a*b+2*a+2*b=(a+2)*(b+2)-2,没推出更多结论,囧.没办法,只能暴力将所有的完美数求出来然后查表.正解是c+2=(a+2)*(b+2);完美数都是有质因子3或5组成的(5本身除外): 自己暴力代码: /****************************************************** * author:xiefubao *****

【程序员的数学思维修炼】总结一

第一章 数据的表示 主要学习了会了 0 不是什么都没有,比如在java里BigDecimal里面是根据最高的那个精度来的,比如1.99+0.01=2.00 这时候提交可能会判错,所以要去掉后导零 为啥要用二进制 还有哪些进制,神奇的八卦,八进制.钟表使用的十二进制.半斤八两十六进制.60年一个甲子六十进制 关于二进制,最主要的是要熟练掌握位运算!一些做题中常用的技巧,比如求n的m次方,判断奇偶,统计一的个数, 这一章里还提到了20!阶乘问题,还记得怎么解决大数阶乘吗. 第二章 神奇的素数 1.验