51nod 1610 路径计数(容斥+dp)

来源:互联网 发布:简单数据库软件 编辑:程序博客网 时间:2024/06/15 06:20

路径计数
System Message (命题人)
基准时间限制:1 秒 空间限制:131072 KB 分值: 80
路径上所有边权的最大公约数定义为一条路径的值。
给定一个有向无环图。
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


gcd=1gcd1100100
gcdO(100n2)
500GG
gcd3gcd=2
mat[k][i][j]kij
i
i

O(Tvn2)O(Tsqrt(v)n2)


代码:

#include <map>#include <set>#include <stack>#include <queue>#include <cmath>#include <string>#include <vector>#include <cstdio>#include <cctype>#include <cstring>#include <sstream>#include <cstdlib>#include <iostream>#include <algorithm>#pragma comment(linker,"/STACK:102400000,102400000")using namespace std;#define   MAX           100005#define   MAXN          1000005#define   maxnode       205#define   sigma_size    2#define   lson          l,m,rt<<1#define   rson          m+1,r,rt<<1|1#define   lrt           rt<<1#define   rrt           rt<<1|1#define   middle        int m=(r+l)>>1#define   LL            long long#define   ull           unsigned long long#define   mem(x,v)      memset(x,v,sizeof(x))#define   lowbit(x)     (x&-x)#define   pii           pair<int,int>#define   bits(a)       __builtin_popcount(a)#define   mk            make_pair#define   limit         10000//const int    prime = 999983;const int    INF   = 0x3f3f3f3f;const LL     INFF  = 0x3f3f;//const double pi    = acos(-1.0);const double inf   = 1e18;//const double eps   = 1e-9;const LL     mod   = 1e9+7;const ull    mx    = 133333331;/*****************************************************/inline void RI(int &x) {      char c;      while((c=getchar())<'0' || c>'9');      x=c-'0';      while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0'; }/*****************************************************/LL dp[105];int a[50005],b[50005],c[50005];int mat[105][105][105];LL g[105];LL f[105];int n;LL dfs(int u,int d){    if(dp[u]!=-1) return dp[u];    LL ans=0;    for(int i=1;i<=n;i++){        if(mat[d][u][i]){            ans=(ans+mat[d][u][i]+mat[d][u][i]*dfs(i,d))%mod;        }    }    return dp[u]=ans;}LL cal(int u){    mem(dp,-1);    for(int i=1;i<=n;i++){        if(dp[i]==-1) dfs(i,u);    }    LL ans=0;    for(int i=1;i<=n;i++) ans=(ans+dp[i])%mod;    return ans;}int main(){    //freopen("in.txt","r",stdin);    int m;    cin>>n>>m;    mem(mat,0);    for(int i=1;i<=m;i++){        scanf("%d%d%d",&a[i],&b[i],&c[i]);        for(int j=1;j*j<=c[i];j++){            if(c[i]%j==0){                mat[j][a[i]][b[i]]++;                if(c[i]/j!=j) mat[c[i]/j][a[i]][b[i]]++;            }        }    }    for(int i=1;i<=100;i++) g[i]=cal(i);    for(int i=100;i>0;i--){        f[i]=g[i];        for(int j=2*i;j<=100;j+=i){            f[i]-=f[j];        }        f[i]=(f[i]%mod+mod)%mod;    }    cout<<f[1]<<endl;    int t;    cin>>t;    while(t--){        int x,y;        scanf("%d%d",&x,&y);        vector<int> v;        for(int i=1;i*i<=c[x];i++){            if(c[x]%i==0){                mat[i][a[x]][b[x]]--;                v.push_back(i);                if(c[x]/i!=i) mat[c[x]/i][a[x]][b[x]]--,v.push_back(c[x]/i);            }        }        c[x]=y;        for(int i=1;i*i<=c[x];i++){            if(c[x]%i==0){                mat[i][a[x]][b[x]]++;                v.push_back(i);                if(c[x]/i!=i) mat[c[x]/i][a[x]][b[x]]++,v.push_back(c[x]/i);            }        }        for(int i=0;i<v.size();i++){            g[v[i]]=cal(v[i]);        }        for(int i=100;i>0;i--){            f[i]=g[i];            for(int j=2*i;j<=100;j+=i){                f[i]-=f[j];            }            f[i]=(f[i]%mod+mod)%mod;        }        cout<<f[1]<<endl;    }    return 0;}
0 0
原创粉丝点击