2014牡丹江 现场赛 F zoj 3824 Fiber-optic Network
首先赞一下题目, 好题
题意:
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 [Li, Ri]. 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的更多相关文章
- zoj 3820(2014牡丹江现场赛B题)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5374 思路:题目的意思是求树上的两点,使得树上其余的点到其中一个点的 ...
- 2014 牡丹江现场赛 A.Average Score(zoj 3819) 解题报告
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5373 题目意思: 有两个class:A 和 B,Bob 在 Clas ...
- 2014 牡丹江现场赛 i题 (zoj 3827 Information Entropy)
I - Information Entropy Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %l ...
- zoj 3827(2014牡丹江现场赛 I题 )
套公式 Sample Input 33 bit25 25 50 //百分数7 nat1 2 4 8 16 32 3710 dit10 10 10 10 10 10 10 10 10 10Sample ...
- zoj 3819(2014牡丹江现场赛 A题 )
题意:给出A班和B班的学生成绩,如果bob(A班的)在B班的话,两个班级的平均分都会涨.求bob成绩可能的最大,最小值. A班成绩平均值(不含BOB)>A班成绩平均值(含BOB) &&a ...
- 2014西安现场赛F题 UVALA 7040
地址 题意:求在m种颜色中挑选k种颜色,给n个花朵涂色有几种方法. 分析:画图可以发现,基本的公式就是k ×(k-1)^(n-1).但这仅保证了相邻颜色不同,总颜色数不超过k种,并没有保证恰好出现k种 ...
- CF GYM100548 (相邻格子颜色不同的方案数 2014西安现场赛F题 容斥原理)
n个格子排成一行,有m种颜色,问用恰好k种颜色进行染色,使得相邻格子颜色不同的方案数. integers n, m, k (1 ≤n, m ≤ 10^9, 1 ≤ k ≤ 10^6, k ≤ n, m ...
- ZOJ 3827 Information Entropy(数学题 牡丹江现场赛)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do? problemId=5381 Information Theory is one of t ...
- 【解题报告】牡丹江现场赛之ABDIK ZOJ 3819 3820 3822 3827 3829
那天在机房做的同步赛,比现场赛要慢了一小时开始,直播那边已经可以看到榜了,所以上来就知道A和I是水题,当时机房电脑出了点问题,就慢了好几分钟,12分钟才A掉第一题... A.Average Score ...
随机推荐
- js中的事件委托或事件代理
一,概述 JavaScript高级程序设计上讲:事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件. 举一个网上大牛们讲事件委托都会举的例子:就是取快递来解释,有三个同事预 ...
- Java-替换字符串中的子字符串
自顶一个repace方法 package com.tj; public class MyClass implements Cloneable { public static void main(Str ...
- Java-构造一个字符串
实用StringBuffer构造字符串 package com.tj; public class MyClass implements Cloneable { public static void m ...
- jsp jstl标签库 el表达式
一.JSTL标签是什么? 提供了对国际化(I18N)的支持,它可以根据发出请求的客户端地域的不同来显示不同的语言. 同时还提供了格式化数据和日期的方法.实现这些功能需要I18N格式标签库(I18N-c ...
- numpy.clip(a, a_min, a_max, out=None)(values < a_min are replaced with a_min, and those > a_max with a_max.)
numpy.clip(a, a_min, a_max, out=None) Clip (limit) the values in an array. Given an interval, values ...
- [uiautomator篇]recent
def Recent(self): d = Device('9410519008004c22098b') displayWidth = int(d.info.get("displayWidt ...
- 一堆Offer怎么选?这样做就不纠结了
有个朋友,工作了10年左右,春节后换工作,拿了三个Offer(西安): 通信行业的一家研究所,软件开发工程师,月薪7K,承诺有月奖金.年终奖金 一家做大数据的公司,软件开发工程师,月薪15K,13薪 ...
- 初学划分树,小见解之!POJ-2104/HDU-2665
划分树 本来是学主席树的,可怜我等巨弱观群巨博客难解fotle主席的思想精髓.于是学了一下划分树,嗯,花了一下午时间理解build(其实自己模拟一遍就通了),我很难理解为什么划分树会看不懂而能学会主席 ...
- scp命令(基于ssh上传文件等)
(转:http://www.cnblogs.com/hitwtx/archive/2011/11/16/2251254.html) svn 删除所有的 .svn文件 find . -name .svn ...
- python 向MySQL里插入中文数据
用python向MySQL中插入中文数据出错,原代码片段: 1 db = MySQLdb.connect("localhost","root","12 ...