(fht.cpp/c/pas)
荷叶叶是一位伟大的数♂学家。 荷叶叶发明了一个函数,并称之为快速荷叶叶变换(Fast H10 Transfrom)
但荷叶叶比较懒,对于函数的计算,荷叶叶把这个任务交给了你。 由于答案可能会很大,请输出答案对1000000007取模的值。
一行,包含两个整数N,M。
1个整数,FHT(N,M) mod 1000000007的值。
fht.in | fht.out |
---|---|
3 4 | 1 |
对于 40% 的数据,1 ≤ N,M ≤ 1000 对于 60% 的数据,1 ≤ N,M ≤ 10 6
对于 100% 的数据,1 ≤ N,M ≤ 10 9
从小到大枚举i发现
i = n … n/2 + 1 时, n mod i = 0, 1, 2, 3, 4, …;i = n/2 … n/3 + 1时, n mod i= n mod (n/2), n mod (n/2) + 2, n mod (n/2) + 4, ……(请读者自己试试)剩下的最后一小段枚举即可。
代码#include <cstdio>#include <cstdlib>using namespace std;const long long mod = 1000000007;long long n, m;inline long long sum(long long s, long long tot, long long c){ return (s + s + (tot - 1) * c % mod) % mod * tot >> 1 % mod;}inline long long solve(long long n) //求出∑i = 1..n n % i { register long long i = 2, l = 0, r = n + 1; long long ans = 0; do { l = r - 1; r = n / i + 1; (ans += sum(n % l, l - r + 1, i - 1)) %= mod; i++; }while(n / (i - 1) - n / i> 1); for(i = 1; i <= r - 1; i++) (ans += n % i) %= mod; return ans;}int main(){ freopen("fht.in", "r", stdin); freopen("fht.out", "w", stdout); long long sum; scanf("%lld%lld", &n, &m); sum = solve(n) * solve(m) % mod; PRintf("%lld/n", sum); return 0;}(phantom.cpp/c/pas)
phantom是一位爱思考的哲♂学家。 最近phantom得到了森の妖精的真传。在他练功的时候, 每秒他的思绪中 都有一定的概率浮现出奇♂异的幻象,持续x秒的幻象将产生x 2 的幻象值。 phantom练功发自真心,他想知道,在N秒内他期望产生的幻象值是多少。
第一行包含 1 个正整数 N ,表示总时间 N 秒。 第二行包含 N 个用空格隔开的在[0,100]之间的正整数,其中第i个数a[i] 表示第i秒浮现幻象的概率为百分之a[i]。
1 个实数,四舍五入后保留一位小数,表示期望幻象值。
phantom.in | phantom.out |
---|---|
3 | 1 |
50 50 50 |
【数据规模与约定】 对于 40%的数据 N ≤ 10 对于 60%的数据 N ≤ 100 对于 100%的数据,N ≤ 10 ^ 6 数据规模较大,请使用效率较高的读入方式。
设L[i]为第i秒幻象的持续时间的期望. 显然L[i] = (L[i-1] + 1) * a[i]% 设f[i]表示前i秒的答案 f[i] = f[i-1] + ((L[i-1] + 1) ^ 2 – L[i-1] ^ 2) * a[i]% 时间复杂度为O(N)
#include <cstdio>#include <cstdlib>using namespace std;const int maxn = 800005;double f[maxn], l[maxn], a[maxn];int n;inline double pow(double x){ return x * x;}int main(){ freopen("phantom.in", "r", stdin); freopen("phantom.out", "w", stdout); register int i, k; scanf("%d", &n); for(i = 1; i <= n; i++) { scanf("%d", &k); a[i] = k / 100.; l[i] = (l[i - 1] + 1) * a[i]; } for(i = 1; i <= n; i++) f[i] = f[i - 1] + (pow(l[i - 1] + 1) - pow(l[i - 1])) * a[i]; printf("%.1lf", f[n]); return 0;}(sherco.cpp/c/pas)
Sherco是一位经验丰富的魔♂法师。 Sherco在第零次圣杯战争中取得了胜利,并取得了王之宝藏——王の树。 他想把这棵树砍去任意条边,拆成若干棵新树,并装饰在他的摩托上,让他 的摩托更加酷炫。 但Sherco认为,这样生成的树不具有美感,于是Sherco想让每棵新树的节 点数相同。 他想知道有多少种方法分割这棵树。
第一行一个正整数N,表示这棵树的结点总数。 接下来N-1行,每行两个数字X,Y表示编号为X的结点与编号为Y的结点 相连。结点编号的范围为[1,N]。
一个整数,表示方案数。注意,不砍去任何一条边也算作一种方案。
【输入输出样例】
sherco.in | sherco.out |
---|---|
6 | 3 |
1 2 | |
2 3 | |
2 4 | |
4 5 | |
5 6 |
对于40%的数据,N ≤ 15 对于60%的数据,N ≤ 10^5 对于100%的数据,N ≤ 10^6 数据规模非常大,请使用高效的读入方式。
暴力枚举删哪些边,期望得分40分。 观察到一些性质: 1.树的大小只可能是N的约数 2.树的大小确定的话,方案最多只有一种 我们可以枚举树的大小,并DFS判定是否可行。 时间复杂度O(n√n),期望得分60分。 继续观察到一些性质: 将原树看做一个有根树,一个节点可以作一个块的”根”, 当且仅当该节点的size能被块的大小整除 预处理出每个节点的size,枚举树的大小k,判断size为k的 倍数的节点数量是否为N/k。 时间复杂度O(NlnN)
#include <cstdio>#include <cstdlib>using namespace std;const int maxn = (int)1e6 + 5;struct edge { int to, next;}e[maxn * 2];struct point { int root, fa;};int n, ans, tot;int h[maxn], size[maxn], p[maxn];inline int read(){ char c; do { c = getchar(); }while(c < '0' || c > '9'); int sum = 0; do { (sum *= 10) += c - 48; c = getchar(); }while('0' <= c && c <= '9'); return sum;}inline void add(int u, int v){ tot++; e[tot] = (edge) {v, h[u]}; h[u] = tot;}void dfs(const point &s){ int i; size[s.root] = 1; for(i = h[s.root]; i; i = e[i].next) if(e[i].to != s.fa) { dfs((point){e[i].to, s.root}); size[s.root] += size[e[i].to]; } p[size[s.root]]++;}int main(){ freopen("sherco.in", "r", stdin); freopen("sherco.out", "w", stdout); int i, j, u, v; n = read(); for(i = 1; i < n; i++) { u = read(); v = read(); add(u, v); add(v, u); } dfs((point){1, 0}); for(i = 1; i <= n; i++) { int sum = p[i]; for(j = 2 * i; j <= n; j += i) sum += p[j]; if(sum * i == n) ans++; } printf("%d/n", ans); return 0;}新闻热点
疑难解答