B - Fractionphp
D - Trianglec++
F - Harmonic Value Description数组
H - Sequence Ipromise
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5912ide
Problem Description
Mr. Frog recently studied how to add two fractions up, and he came up with an evil idea to trouble you by asking you to calculate the result of the formula below:this
As a talent, can you figure out the answer correctly?
idea
Input
The first line contains only one integer T, which indicates the number of test cases.spa
For each test case, the first line contains only one integer n (n≤8).code
The second line contains n integers: $a_1,a_2,⋯a_n(1\le a_i \le 10)$.
The third line contains n integers: $b_1,b_2,⋯,b_n(1 \le b_i \le 10)$.
Output
For each case, print a line “Case #x: p q”, where x is the case number (starting from 1) and p/q indicates the answer.
You should promise that p/q is irreducible.
Sample Input
1
2
1 1
2 3
Sample Output
Case #1: 1 2
Hint
Here are the details for the first sample:
2/(1+3/1) = 1/2
题意:
给出了关于 $a[1:n]$ 和 $b[1:n]$ 的计算式,给你 $a[1:n]$ 和 $b[1:n]$,要求计算式结果。
题解:
因为范围很小,直接递归计算便可。
AC代码:
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> pii; const int maxn=10; int n; int a[maxn],b[maxn]; inline int gcd(int m,int n){return n?gcd(n,m%n):m;} pii dfs(int dist) { if(dist==n) { int u=b[n]; int d=a[n]; int g=gcd(u,d); return make_pair(u/g,d/g); } pii f=dfs(dist+1); int u=b[dist]*f.second; int d=a[dist]*f.second+f.first; int g=gcd(u,d); return make_pair(u/g,d/g); } int main() { int T; cin>>T; for(int kase=1;kase<=T;kase++) { cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++) cin>>b[i]; pii ans=dfs(1); printf("Case #%d: %d %d\n",kase,ans.first,ans.second); } }
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5914
Input
The first line contains only one integer T (T≤20), which indicates the number of test cases. For each test case, there is only one line describing the given integer n (1≤n≤20).
Output
For each test case, output one line “Case #x: y”, where x is the case number (starting from 1), y is the minimal number of sticks Wallice should steal.
Sample Input
3 4 5 6
Sample Output
Case #1: 1 Case #2: 1 Case #3: 2
题意:
有 $n$ 根棍子,长度分别为 $1,2,3,\cdots,n$,如今要从中取出若干棍子使得剩下的棍子任意三条均不能组成一个三角形,求最少取出多少根棍子。
题解:
首先考虑最开始的 $1,2,3$ 三根木棍都是能够留下来的,而长度为 $4$ 的则须要拿走,由于 $2+3>4$,而后 $5$ 又能够留下, 由于正好 $2+3=5$,依次类推,不难发现就是一个斐波那契数列。
AC代码:
#include<bits/stdc++.h> using namespace std; const int maxn=25; int n; int fibo[maxn]; int main() { int T; cin>>T; fibo[1]=1; fibo[2]=2; for(int i=3;i<maxn;i++) fibo[i]=fibo[i-1]+fibo[i-2]; for(int kase=1;kase<=T;kase++) { cin>>n; printf("Case #%d: %d\n",kase,n-(upper_bound(fibo+1,fibo+maxn,n)-(fibo+1))); } }
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5916
The harmonic value of the permutation $p_1,p_2,⋯,p_n$ is
$\sum\limits_{i = 1}^{n - 1} {\left( {p_i p_{i + 1} } \right)}$
Mr. Frog is wondering about the permutation whose harmonic value is the strictly k-th smallest among all the permutations of [n].
Input
The first line contains only one integer T (1≤T≤100), which indicates the number of test cases.
For each test case, there is only one line describing the given integers n and k (1≤2k≤n≤10000).
Output
For each test case, output one line “Case #x: $p_1$ $p_2$ ⋯ $p_n$”, where x is the case number (starting from 1) and $p_1$ $p_2$ ⋯ $p_n$ is the answer.
Sample Input
2
4 1
4 2
Sample Output
Case #1: 4 1 3 2
Case #2: 2 4 1 3
题意:
给出 $[1:n]$ 的一个排列 $p_1$ $p_2$ ⋯ $p_n$,认为其调和值为 $\sum\limits_{i = 1}^{n - 1} {\left( {p_i p_{i + 1} } \right)}$,
如今对于 $[1:n]$ 的全部排列,要求其调和值为第 $k$ 小的排列是哪个。
题解:
首先 $1,2,3,4,5,6\cdots,n$ 这样的排列,很明显“调和值”最小,为 $n-1$,
若咱们把 $2$ 移动至 $3,4$ 之间的位置,就会变成:$1,3,2,4,5,6,\cdots ,n$,不难发现,调和值为 $n$,由于从 $4$ 日后的全部数字都没有变化,gcd值仍是 $1$,惟一变化的是 $2,4$ 的gcd值为 $2$,也就是原来多了 $1$,
能够大胆假设:第 $k$ 小调和值的排列,就是把 $1,2,3,4,5,6\cdots,n$ 中的 $k$ 取出来,放到 $2k-1,2k$ 之间。
不妨检验一下 $k=3$,咱们先将 $3$ 移至 $5,6$ 之间获得:$1,2,4,5,3,6,7,8,\cdots,n$,发现 $gcd(3,6) = 3$,确实比原来增长了2,
可是,存在问题, 本来 $2,4$ 由 $3$ 隔开,如今并到了一块儿,gcd值也增长了,那么咱们不妨把 $1$ 拿过来填掉这个原来是 $3$ 的坑,获得:$2,1,4,5,3,6,7,8,\cdots,n$,调和值为 $n+1$,就是第 $3$ 小的,完美。
因此,对于任意的 $k$ 知足 $2k \le n$,只要将 $k$ 移动至 $2k$ 以前,将 $1$ 移动至原来 $k$ 的位置,就能获得调和值第 $k$ 小的排列。
(不由自主就像$%$一下个人神仙队友,这都能想获得,tql(`・ω・´)>)
AC代码:
#include<bits/stdc++.h> using namespace std; const int maxn=25; int n,k; int main() { int T; cin>>T; for(int kase=1;kase<=T;kase++) { cin>>n>>k; printf("Case #%d: ",kase); if(k==1) for(int i=1;i<=n;i++) printf("%d%c",i,(i==n)?'\n':' '); else { for(int i=2;i<=k-1;i++) printf("%d ",i); printf("1 "); for(int i=k+1;i<=2*k-1;i++) printf("%d ",i); printf("%d ",k); for(int i=2*k;i<=n;i++) printf("%d%c",i,(i==n)?'\n':' '); } } }
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5918
Mr. Frog has two sequences $a_1,a_2,⋯,a_n$ and $b_1,b_2,⋯,b_m$ and a number $p$. He wants to know the number of positions $q$ such that sequence $b_1,b_2,⋯,b_m$ is exactly the sequence $a_q,a_{q+p},a_{q+2p},⋯,a_{q+(m−1)p}$ where $q+(m−1)p \le n$ and $q \ge 1$.
Input
The first line contains only one integer $T \le 100$, which indicates the number of test cases.Each test case contains three lines.
The first line contains three space-separated integers $1 \le n \le 10^6,1 \le m \le 10^6$ and $1 \le p \le 10^6$.
The second line contains $n$ integers $a_1,a_2,⋯,a_n(1 \le a_i \le 10^9)$. The third line contains $m$ integers $b_1,b_2,⋯,b_m(1 \le b_i \le 10^9)$.
Output
For each test case, output one line “Case #x: y”, where x is the case number (starting from 1) and y is the number of valid q’s.
Sample Input
2
6 3 1
1 2 3 1 2 3
1 2 3
6 3 2
1 3 2 2 3 1
1 2 3
Sample Output
Case #1: 2
Case #2: 1
题意:
给出一个长度为 $n$ 的文本串,一个长度为 $m$ 的模式串,给出跳步长度 $p$,
要求在文本串中,若按照跳步长度 $p$ 来进行遍历,求能找获得多少个模式串。
题解:
特喵的这个就是个KMP模板题,一开始看完题目就想着枚举开头,把全部的跳步长度为 $p$ 的子序列处理出来了,
可是那个时候不知道发什么神经,竟然算不清处理出来的若干个子序列的总长是多少!!!觉得是 $O(n^2)$ 的总长度就没敢写,后来一看榜单怎么过的人这么多,确定就是个水题啊!
而后仔细一看,就反应过来了,这若干个子序列的总长就是 $O(n)$ 啊!
假设文本串的编号是 $0$ 到 $n-1$ 的,那么咱们只须要开一个表头大小为 $p$ 的邻接表来存这若干个子序列(表头就是 $0,1,2,\cdots,p-1$),对于编号为 $i$ 那个字符,扔进表头为 $i%p$ 的那个链表里去就好了呀!!!每一个字符确定只会出现一次,因此这若干个子序列的总长就是 $O(n)$……
而后就好办了,对邻接表里的每一个链表,就当成一个文本串,拿去和模式串KMP匹配一下,求得当前子序列中出现了几回模式串,最后求和一下就是答案了;
总的时间复杂度 $O(n+m)$。
AC代码:
#include<bits/stdc++.h> using namespace std; const int maxn=1e6+10; int n,m,p; vector<int> str[maxn]; int pat[maxn]; int Next[maxn]; void getNext() { int i=0, j=-1, len=m; Next[0]=-1; while(i<len) { if(j == -1 || pat[i] == pat[j]) Next[++i]=++j; else j=Next[j]; } } int kmp(int p) { int i=0, j=0, len1=str[p].size(), len2=m; if(len1<len2) return 0; int ans=0; while(i<len1) { if(j == -1 || str[p][i] == pat[j]) i++, j++; else j=Next[j]; if(j == len2) ans++; } return ans; } int main() { int T; cin>>T; for(int kase=1;kase<=T;kase++) { scanf("%d%d%d",&n,&m,&p); for(int i=0;i<p;i++) str[i].clear(); for(int i=0,a;i<n;i++) { scanf("%d",&a); str[i%p].push_back(a); } for(int i=0;i<m;i++) scanf("%d",&pat[i]); pat[m]=0; getNext(); int ans=0; for(int i=0;i<p;i++) ans+=kmp(i); printf("Case #%d: %d\n",kase,ans); } }
注意:
这里有一个WA点,首先KMP的模板是没错的,可是KMP的模板对应的是char数组的字符串,而咱们这里是数字序列;
咱们都知道,字符串读入时,位置 $0 \sim n-1$ 存实际字符串,位置 $n$ 存一个 '\0',KMP的模板里是有使用到这个性质的;
而当咱们for循环读入数字时,是没有这个 '\0' 终止符的,因此咱们应当相似于字符串读入的方式,在位置 $n$ 存一个 $0$(将全部序列可能出现的数字做为一个集合,取该集合范围以外的数字)做为终止符。
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5919
Mr. Frog has an integer sequence of length n, which can be denoted as $a_1,a_2,⋯,a_n$.
There are m queries. In the i-th query, you are given two integers $l_i$ and $r_i$. Consider the subsequence $a_{l_i},a_{l_{i+1}},a_{l_{i+2}},⋯,a_{r_i}$.
We can denote the positions (the positions according to the original sequence) where an integer appears first in this subsequence as $p_1^{(i)},p_2^{(i)},⋯,p_{k_i}^{(i)}$ (in ascending order, i.e., $p_1^{(i)} < p_2^{(i)} < ⋯ < p_{k_i}^{(i)}$).
Note that $k_i$ is the number of different integers in this subsequence. You should output $p_{\left\lceil {\frac{{k_i }}{2}} \right\rceil }^{(i)}$ for the i-th query.
Input
In the first line of input, there is an integer T (T≤2) denoting the number of test cases.
Each test case starts with two integers n (n≤2e5) and m (m≤2e5).
There are n integers in the next line, which indicate the integers in the sequence(i.e., $a_1,a_2,⋯,a_n$, $0 \le a_i \le 2e5$).
There are two integers $l_i$ and $r_i$ in the following $m$ lines.
However, Mr. Frog thought that this problem was too young too simple so he became angry. He modified each query to $l'_i,r'_i$($1 \le l'_i \le n, 1 \le r'_i \le n$).
As a result, the problem became more exciting. We can denote the answers as $ans_1,ans_2,⋯,ans_m$.
Note that for each test case $ans_0=0$.
You can get the correct input $l_i,r_i$ from what you read (we denote them as $l'_i,r'_i$) by the following formula: $l_i = min{(l'_i+ans_{i−1}) mod n + 1,(r'_i + ans_{i−1}) mod n+1}, r_i = max{(l'_i + ans_{i−1}) mod n + 1, (r'_i+ans_{i−1}) mod n + 1}$
Output
You should output one single line for each test case. For each test case, output one line “Case #x: $ans_1,ans_2,⋯,ans_m$”, where x is the case number (starting from 1) and $ans_1,ans_2,⋯,ans_m$ is the answer.
题意:
给出 $n(n \le 2e5)$ 个数,每一个数的大小知足 $0 < a_i \le 2e5$,
给出 $m(m \le 2e5)$ 个询问,对于每一个询问输入 $l,r$,序列 $a_l,...,a_r$ 中的每一个数,在该序列内第一次出现的位置,合成一个序列 $P$;
若假设这个区间有 $k$ 个不一样的数,咱们获得的序列 $P$ 就是 $p_1 < p_2 < p_3 < ... <p_k$;
而对应于该查询的答案为:序列中 $P$ 的第 $\left\lceil {\frac{k}{2}} \right\rceil = \left\lfloor {\frac{{k + 1}}{2}} \right\rfloor$ 个数。
例如:
整个序列为:$1,5,2,2,5,1,4,5,1$;
查询区间为 $[1,5]$,即 $1,5,2,2,5$,对应产生的序列 $P$ 即为 $1,2,3$,长度 $k=3$,答案为 $p_{\left\lfloor {\frac{{3 + 1}}{2}} \right\rfloor } = p_2 = 2$;
查询区间为 $[2,7]$,即 $5,2,2,5,1,4$,对应产生的序列 $P$ 即为 $2,3,6,7$,长度 $k=4$,答案为 $p_{\left\lfloor {\frac{{4 + 1}}{2}} \right\rfloor } = p_2 = 3$;
查询区间为 $[6,9]$,即 $1,4,5,1$,对应产生的序列 $P$ 即为 $6,7,8$,长度 $k=3$,答案为 $p_{\left\lfloor {\frac{{3 + 1}}{2}} \right\rfloor } = p_2 = 7$;
(固然,查询的输入那里加了一点小操做,不影响总体大意,第 $i$ 个查询的区间要经过 第 $i-1$ 个查询的答案计算获得)。
题解: