1610 路径计数

基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
 
路径上所有边权的最大公约数定义为一条路径的值。

给定一个有向无环图。
T次修改操作,每次修改一条边的边权,每次修改后输出有向无环图上路径的值为1的路径数量(对1,000,000,007取模)。
Input
第一行两个整数n和m,分别表示有向无环图上的点数和边数。(1<=n<=100,1<=m<=50,000)
第2~m+1行每行三个数x,y,z,表示有一条从x到y权值为z的边。(1<=x,y<=n,1<=z<=100)
第m+2行一个数T,表示修改操作次数(1<=T<=500)。
接下来T行每行两个数x,y,表示修改第x条边(按照读入的顺序)的边权为y(1<=x<=m,1<=y<=100)。
Output
T+1行,修改前和每次修改操作后输出答案。
Input示例
4 4
1 2 2
2 4 3
1 3 4
3 4 2
4
1 5
2 10
3 3
4 6
Output示例
1
1
0
1
0
/*
51 nod 1610 路径计数(Moblus+dp) problem:
路径上所有边权的最大公约数定义为一条路径的值。给定一个有向无环图。
T次修改操作,每次修改一条边的边权,每次修改后输出有向无环图上路径的值为1的路径数量(对1,000,000,007取模)。 solve:
感觉直接在图上求GCD的话很麻烦,而且还涉及到修改.
后来发现可以考虑通过容斥来求GCD,这样的话就转换成了图上面长度为i的路径的个数.
开始时记录路径长度w[i]以及它的约数. (w[i] = 4的话, 可以看成有 1,2,4三条边) 于是通过枚举gcd便能够在 100*n*n内求出来所有路径值的情况.
在修改的时候,可以发现只会 影响被移除的数和添加的数以及它们的约数. 处理一下
然后通过moblus实现容斥就能求出gcd = 1的情况. hhh-2016/09/09-20:59:44
*/
#pragma comment(linker,"/STACK:124000000,124000000")
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <cstring>
#include <vector>
#include <math.h>
#include <queue>
#include <set>
#include <map>
#define lson i<<1
#define rson i<<1|1
#define ll long long
#define clr(a,b) memset(a,b,sizeof(a))
#define scanfi(a) scanf("%d",&a)
#define scanfs(a) scanf("%s",a)
#define scanfl(a) scanf("%I64d",&a)
#define scanfd(a) scanf("%lf",&a)
#define key_val ch[ch[root][1]][0]
#define eps 1e-7
#define inf 0x3f3f3f3f3f3f3f3f
using namespace std;
const ll mod = 1000000007;
const int maxn = 135;
const double PI = acos(-1.0);
const int limit = 33; template<class T> void read(T&num)
{
char CH;
bool F=false;
for(CH=getchar(); CH<'0'||CH>'9'; F= CH=='-',CH=getchar());
for(num=0; CH>='0'&&CH<='9'; num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p)
{
if(!p)
{
puts("0");
return;
}
while(p) stk[++ tp] = p%10, p/=10;
while(tp) putchar(stk[tp--] + '0');
putchar('\n');
}
int n,m,q,id;
ll dp[maxn],num[maxn];
ll ma[maxn][maxn][maxn]; int tot;
int is_prime[maxn];
ll mu[maxn];
int prime[maxn]; void Moblus()
{
tot = 0;
mu[1] = 1;
memset(is_prime,0,sizeof(is_prime));
for(int i = 2; i < maxn-10; i++)
{
if(!is_prime[i])
{
prime[tot++] = i;
mu[i] = -1;
} for(int j = 0; j < tot && i*prime[j] < maxn-10; j++)
{
is_prime[i*prime[j]] = 1;
if(i % prime[j])
{
mu[i*prime[j]] = -mu[i];
}
else
{
mu[i*prime[j]] = 0;
break;
}
}
}
} ll dfs(int u,int gcd)
{
if(dp[u] != -1) return dp[u];
ll ans = 0;
for(int i = 1; i <= n; i++)
{
if(ma[gcd][u][i])
{
ans = (ll)(ans + ma[gcd][u][i] + (ll)ma[gcd][u][i]*dfs(i,gcd)%mod)%mod;
}
}
return dp[u] = ans;
} ll solve(int gcd)
{
clr(dp,-1);
ll ans = 0;
for(int i = 1; i <= n; i++)
{
if(dp[i] == -1)
dfs(i,gcd);
}
for(int i = 1; i <= n; i++)
ans = (ans + dp[i])%mod;
return ans;
} void debug()
{
for(int i = 1; i <= 10; i++)
{
num[i] = solve(i);
cout << num[i] <<" ";
}
cout << endl;
} int u[maxn*maxn*5],vec[maxn*maxn*5];
int v[maxn*maxn*5];
int x[maxn*maxn*5];
int main()
{
// freopen("in.txt","r",stdin);
int y;
Moblus();
read(n),read(m);
memset(ma,0,sizeof(ma));
for(int i = 1; i <= m; i++)
{
read(u[i]),read(v[i]);
read(x[i]);
for(int j = 1; j * j <= x[i]; j++)
{
if(x[i] % j) continue;
ma[j][u[i]][v[i]] ++;
if(j * j != x[i])
ma[x[i]/j][u[i]][v[i]] ++;
}
}
for(int i = 1; i <= 100; i++)
{
num[i] = solve(i);
}
// debug();
read(q);
ll ans = 0;
for(int i = 1; i <= 100; i++)
{
ans = (ans + (ll)mu[i] * num[i] +mod)%mod;
}
printf("%I64d\n",ans);
int id,cnt;
for(int i = 1; i <= q; i++)
{
ans = 0,cnt = 0;
read(id),read(y);
int a = u[id],b = v[id];
for(int i = 1; i*i <= x[id]; i++)
{
if(x[id] % i) continue;
ma[i][a][b] --,vec[cnt++] = i;
if(i * i != x[id])
ma[x[id]/i][a][b] --,vec[cnt++] = x[id]/i;
}
x[id] = y;
for(int i = 1; i*i <= x[id]; i++)
{
if(x[id] % i) continue;
ma[i][a][b] ++,vec[cnt++] = i;
if(i*i != x[id])
ma[x[id]/i][a][b] ++,vec[cnt++] = x[id]/i;
} for(int i = 0; i < cnt; i++)
{
num[vec[i]] = solve(vec[i]);
}
// debug();
for(int i = 1; i <= 100; i++)
{
ans = (ans + (ll)mu[i] * num[i]+mod)%mod;
}
printf("%I64d\n",ans);
}
return 0;
}

  

51 nod 1610 路径计数(Moblus+dp)的更多相关文章

  1. 51 nod 1055 最长等差数列(dp)

    1055 最长等差数列 基准时间限制:2 秒 空间限制:262144 KB 分值: 80 难度:5级算法题 N个不同的正整数,找出由这些数组成的最长的等差数列.     例如:1 3 5 6 8 9 ...

  2. 51 nod 1682 中位数计数

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1682 1682 中位数计数 基准时间限制:1 秒 空间限制: ...

  3. 51 nod 1522 上下序列——序列dp

    题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1522 很好的思想.考虑从小到大一对一对填数,这样也能对它的大小限制 ...

  4. 51 Nod 1352 集合计数

    大致题意:求ax+by=n+1的正数解的个数. 先看下面: 相信看过了通解的参数表示后已经知道怎么解了,贴代码: #include <bits/stdc++.h> #define ll l ...

  5. 51 nod 1439 互质对(Moblus容斥)

    1439 互质对 题目来源: CodeForces 基准时间限制:2 秒 空间限制:131072 KB 分值: 160 难度:6级算法题 有n个数字,a[1],a[2],…,a[n].有一个集合,刚开 ...

  6. 51 nod 1427 文明 (并查集 + 树的直径)

    1427 文明 题目来源: CodeForces 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 160 难度:6级算法题   安德鲁在玩一个叫“文明”的游戏.大妈正在帮助他. 这个游 ...

  7. 51 nod 1766 树上的最远点对(线段树+lca)

    1766 树上的最远点对 基准时间限制:3 秒 空间限制:524288 KB 分值: 80 难度:5级算法题   n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间,表示点的标号请你求出两个 ...

  8. 51 nod 1456 小K的技术(强连通 + 并查集)

    1456 小K的技术 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题   苏塞克王国是世界上创新技术的领先国家,在王国中有n个城市 ...

  9. 【洛谷】P1176: 路径计数2【递推】

    P1176 路径计数2 题目描述 一个N×N的网格,你一开始在(1,1),即左上角.每次只能移动到下方相邻的格子或者右方相邻的格子,问到达(N,N),即右下角有多少种方法. 但是这个问题太简单了,所以 ...

随机推荐

  1. choose the max from numbers, use scanf and if else (v1:21.9.2017,v2:23.9.2017)

    #include<stdio.h> int main(){ int a,b,c,max; printf("请输入一个数值: "); scanf("%d&quo ...

  2. 团队作业4——第一次项目冲刺(Alpha版本)11.14

    a. 提供当天站立式会议照片一张 举行站立式会议,讨论项目安排: PM对整个项目的需求进行讲解: 全队对整个项目的细节进行沟通: 对整个项目的开发计划进行分析,分配每天的任务: 统一确定项目的开发环境 ...

  3. 第四十四条:为所有导出的API元素编写文档注释

    简而言之,要为API编写文档,文档注释是最好,最有效的途径.对于所有可导出的API元素来说,使用文档注释应该被看作是强制性的.要 采用一致的风格来遵循标准的约定.记住,在文档注释内部出现任何的HTML ...

  4. 自己动手写CPU(基于FPGA与Verilog)

    大三上学期开展了数字系统设计的课程,下学期便要求自己写一个单周期CPU和一个多周期CPU,既然要学,就记录一下学习的过程. CPU--中央处理器,顾名思义,是计算机中最重要的一部分,功能就是周而复始地 ...

  5. 关于移动web教程免费发布

    各位老铁大家好,最近经历了太多太多,精力一直不能集中做自己愿意做的事情. 移动Web课程一开始设置收费10块,其实本意是让大家感觉有支出,就会相对珍惜好好学习,但是发现收费把大部分人挡在门外,现在恢复 ...

  6. php的借用其他网站的页面覆盖Logo的技巧

    php的借用其他网站的页面覆盖Logo的技巧, <body> <div id="red_f"></div> <div class=&quo ...

  7. WebApi 的三种寄宿方式 (一)

    最近逛博客园,看到了Owin,学习了一下,做个笔记,说不定将来哪天就用上了 关于 Owin 的介绍,百度解释的很清楚了: https://baike.baidu.com/item/owin/28607 ...

  8. 原生JS封装时间运动函数

    /*讲时间运动之前先给大家复习一下运动函数 通常大家都会写运动框架,一个定时器(Timer),一个步长(step 就是每次运动的距离),一个当前位置(current)一个目标位置(target),然后 ...

  9. linux下的Shell编程(4)特殊的变量和占位符

    $#表示包括$0在内的命令行参数的个数.在Shell中,脚本名称本身是$0,剩下的依次是$0.$1.$2-.${9},等等. $*表示整个参数列表,不包括$0,也就是说不包括文件名的参数列表. $?表 ...

  10. bootstrap 一个简单的登陆页面

    效果如图:用bootstrap 写的一个简单的登陆 一.修改样式 样式可以自己调整,例如换个背景色之类的,修改 background-color属性就可以 #from { background-col ...