首先赞一下题目, 好题

题意:

Marjar University has decided to upgrade the infrastructure of school intranet by using fiber-optic technology. There are N buildings in the school. Each building will be installed with one router. These routers are connected by optical cables in such a way that there is exactly one path between any two routers.

Each router should be initialized with an operating frequency Fi before it starts to work. Due to the limitations of hardware and environment, the operating frequency should be an integer number within [LiRi]. In order to reduce the signal noise, the operating frequency of any two adjacent routers should be co-prime.

Edward is the headmaster of Marjar University. He is very interested in the number of different ways to initialize the operating frequency. Please write a program to help him! To make the report simple and neat, you only need to calculate the sum of Fi (modulo 1000000007) in all solutions for each router.

英文自己看。 大概意思就是一棵树上每一个点i能够给一个L[i] ~ R[i]的值, 相邻的两个点的值要互质, 问每一个点的全部情况的值的和, mod 1000000007

大概思路就是枚举一个点, 然后枚举这个点上的值(i)。 然后求出这种情况有多少种(dp[i]), 那么这个点上的答案就是 dp[1] * 1 + dp[2] * 2 + dp[3] * 3 + .........

然后就是树形dp了, 转移方程就是 dp[i][j] =π{(∑{dp[t][k] | gcd(j, k) == 1}) | i 和 t 相邻}

可是这样转移的复杂度是50 * 50000 * 50000, 就算15秒时限也会超时

所以我们能够考虑用不互质的来转移。

设s[i] = ∑dp[i][j]

那么转移方程就是   dp[i][j] =π{(s[i] - ∑{dp[t][k] | gcd(j, k) != 1}) | i 和 t 相邻}

对于dp[i][j],我们能够把 j 质因数分解, 如果 j = p1^e1 * p2^e2 * p3^e3。 50000以内的数最多有6个不同的质因数;

然后我们记录一下 div[i][k] = ∑{ dp[i][j] | j 是 k 的倍数}, 这个能够nlogn的复杂度处理出来;

这样  ∑{dp[t][k] | gcd(j, k) != 1} = div[t][p1] + div[t][p2] + div[t][p3] - div[t][p1 * p2] - div[t][p1 * p3] - div[t][p2 * p3] + div[t][p1 * p2 * p3], 这样能够用容斥原理算了, 复杂度最多为2 ^ 6;

这样dp一次复杂度大概就是 50 * 50000 * (log50000 + 2^6);

要算50个点的话。 还是会超时;

可是这是一颗树。 对每一个点都dp一次的话算了非常多反复的东西, 所以我们不要每次都去所有dp一次, 比如算完i点的了, 要去算j点的, 如果i j相邻。 那么在dp数组中仅仅有i和j的值有变化。 我们就仅仅要再算这两个点的dp转移就够了。

很多其它细节请看代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <vector>using namespace std;typedef long long LL;
const int N = 50009;
const LL M = 1000000007;inline void addIt(int &a, int b)
{a += b;if(a >= M) a -= M;
}inline int sub(int a, int b)
{a -= b;if(a < 0) a += M;if(a >= M) a -= M;return a;
}struct Num
{int p[11];int allp;
}num[N];struct Data
{int dp[N], div[N], all;
}data[55], fb[55];int L[55], R[55];
int ans[55];
int n;
vector<int> e[55];
bool vis[55];
int rcn, rcv;void print()
{for(int i = 0; i < n; i++){printf("i = %d\n", i);for(int j = 0; j < 6; j++) printf("dp[%d] = %d\n", j, data[i].dp[j]);}
}int rc(int i, int xs)
{int t, r = 0;for(; i < num[rcn].allp; i++){if(xs * num[rcn].p[i] <= R[rcv]) t = data[rcv].div[xs * num[rcn].p[i]];else t = 0;//printf("***%d, t = %d\n", xs * num[rcn].p[i], t);addIt(r, sub(t, rc(i + 1, xs * num[rcn].p[i])));}//printf("r = %d\n", r);return r;
}void dfsTree(int pre, int now)
{if(vis[now]) return;vis[now] = true;int i, siz = e[now].size();for(i = 0; i < siz; i++) dfsTree(now, e[now][i]);if(pre >= 0 && siz <= 1) for(i = L[now]; i <= R[now]; i++) data[now].dp[i] = 1;else for(i = L[now]; i <= R[now]; i++){data[now].dp[i] = 1;for(int j = 0; j < siz; j++) if(e[now][j] != pre){rcn = i;rcv = e[now][j];data[now].dp[i] = (LL)(data[now].dp[i]) * sub(data[e[now][j]].all, rc(0, 1)) % M;}}data[now].all = 0;for(i = 1; i <= R[now]; i++){data[now].div[i] = 0;for(int j = i; j <= R[now]; j += i) if(j >= L[now]) addIt(data[now].div[i], data[now].dp[j]);if(i >= L[now]) addIt(data[now].all, data[now].dp[i]);}
}void dfs(int pre, int now, int deep)
{dfsTree(-1, now);//if(now == 1) print();int i, siz = e[now].size();ans[now] = 0;for(i = L[now]; i <= R[now]; i++) addIt(ans[now], (LL)data[now].dp[i] * i % M);//fb[deep] = data[now];//vis[now] = false;for(i = 0; i < siz; i++) if(e[now][i] != pre){vis[e[now][i]] = false;fb[deep] = data[e[now][i]];vis[now] = false;dfs(now, e[now][i], deep + 1);data[e[now][i]] = fb[deep];vis[e[now][i]] = true;}
}void init()
{int i, j, k;for(i = 0; i < N; i++) num[i].allp = 0;for(i = 2; i < N; i++) if(num[i].allp == 0) for(j = i; j < N; j += i) num[j].p[num[j].allp++] = i;
}int main()
{//freopen("13F.in", "r", stdin);init();int T;scanf("%d", &T);while(T--){scanf("%d", &n);int i, j, k;for(i = 0; i < n; i++){scanf("%d", &L[i]);}for(i = 0; i < n; i++){scanf("%d", &R[i]);e[i].clear();}for(i = 0; i < n - 1; i++){scanf("%d %d", &j, &k);j--;k--;e[j].push_back(k);e[k].push_back(j);}memset(vis, false, sizeof(vis));memset(data, 0, sizeof(data));dfsTree(-1, 0);//print();dfs(-1, 0, 0);for(i = 0; i < n - 1; i++) printf("%d ", ans[i]); printf("%d\n", ans[i]);}return 0;
}

2014牡丹江 现场赛 F zoj 3824 Fiber-optic Network相关推荐

  1. ZOJ 3827 Information Entropy(数学题 牡丹江现场赛)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do? problemId=5381 Information Theory is one of t ...

  2. 2014ACM/ICPC亚洲区域赛牡丹江现场赛总结

    不知道怎样说起-- 感觉还没那个比赛的感觉呢?如今就结束了. 9号.10号的时候学校还评比国奖.励志奖啥的,由于要来比赛,所以那些事情队友的国奖不能答辩.自己的励志奖班里乱搞要投票,自己又不在,真是无 ...

  3. zoj 3809 枚举水题 (2014牡丹江网赛 A题)

    题目大意:给出一列取样的几个山的高度点,求山峰有几个? Sample Input 2 9 1 3 2 4 6 3 2 3 1 5 1 2 3 4 5 Sample Output 3 0 1 # inc ...

  4. The 2014 ACM-ICPC Asia Mudanjiang Regional Contest(2014牡丹江区域赛)

    The 2014 ACM-ICPC Asia Mudanjiang Regional Contest 题目链接 没去现场.做的网络同步赛.感觉还能够,搞了6题 A:这是签到题,对于A堆除掉.假设没剩余 ...

  5. 华中邀请赛现场赛F题 Seats

    题目链接:http://acm.whu.edu.cn/land/problem/detail?problem_id=1552 解题报告:题目意思应该很清楚,就是有n个人,分别属于7个班级,然后他们坐成 ...

  6. 2018ACM-ICPC 焦作站现场赛 F. Honeycomb(BFS求最短路,卡memset)

    F. Honeycomb 从前不信命,从这道题开始,我信了. 我就是没有拿牌子的命.这道题或者说这个memset,击碎了我所有对ACM的美好记忆. #include<bits/stdc++.h& ...

  7. hdu 5078 2014鞍山现场赛 水题

    http://acm.hdu.edu.cn/showproblem.php?pid=5078 现场最水的一道题 连排序都不用,因为说了ti<ti+1 //#pragma comment(link ...

  8. hdu 5131 (2014广州现场赛 E题)

    题意:对给出的好汉按杀敌数从大到小排序,若相等,按字典序排.M个询问,询问名字输出对应的主排名和次排名.(排序之后)主排名是在该名字前比他杀敌数多的人的个数加1,次排名是该名字前和他杀敌数相等的人的个 ...

  9. 2014牡丹江网络赛ZOJPretty Poem(暴力枚举)

    /* 将给定的一个字符串分解成ABABA 或者 ABABCAB的形式! 思路:暴力枚举A, B, C串! */ 1 #include<iostream> 2 #include<cst ...

最新文章

  1. CVPR 2022|处理速度仅用0.2秒!港科大腾讯AI lab开源基于GAN反演的高保真图像编辑算法...
  2. 软件需求工程与UML建模——第九组第二周工作总结
  3. 寄存器(内存访问)---汇编学习笔记
  4. Grove-Lora Radio:修改库函数使能修改扩频因子、带宽参数、码率
  5. python itertools.product_在python中,如何拆分itertools.product分组并在p中迭代
  6. 计算机软件通常分为两大类 它们是,计算机考试题库:计算机考试练习题(79)...
  7. Confluence 6 管理协同编辑 - 最大编辑者的限制
  8. IE下的一个安全BUG —— 可实时跟踪系统鼠标位置
  9. Elasticsearch 日期时间处理
  10. phpmyadmin-错误:配置文件权限错误,不应任何用户都能修改!这里有答案
  11. 申通上云?技术详解! | 凌云时刻
  12. 《算法笔记》和《算法笔记上机训练指南》学习笔记汇总
  13. 触摸按键设计参考与问题总结
  14. IP地址(IPv4)
  15. 当自己觉得特别迷茫的时候,是怎么走出这个困境的
  16. 查询ES(ElasticSearch)版本
  17. html doc全称,html标签全称和功能介绍.doc
  18. import time python_import time
  19. 国外计算机cpu排行,电脑处理器排行榜_电脑处理器排行榜最新2020
  20. 分享一个 C# Winfrom 下的 OutlookBar 控件的使用

热门文章

  1. 边缘计算智慧灯杆网关——数据传输的桥梁
  2. 洛谷 P2341 【HAOI2006】受欢迎的牛
  3. 科创板影子股投机调研
  4. javamail解析邮件内容中含有图片
  5. 论文笔记——Camouflaged Object Detection
  6. clang-llvm跨平台编译
  7. 锐捷云桌面持续领跑的背后
  8. 爱沙尼亚Rainbow数字资产交易平台即将登场,赶紧来围观!
  9. Excel如何将某一工作表复制多份并自定义名称
  10. 解决R语言报错:Error in make.names(col.names, unique = TRUE) :文件编码不一致的问题