编程马拉松17C

#include <algorithm>
#include <assert.h>
#include <complex>
#include <ctype.h>
#include <functional>
#include <iostream>
#include <limits.h>
#include <locale.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <vector>
//#include <unordered_set>
//#include <unordered_map>

#pragma warning(disable:4996)
using namespace std;

#define mp make_pair
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <ll, int> pli;
typedef pair <ldb, ldb> pdd;

int IT_MAX = 1 << 21;
const int MOD = 1000000007;
const int INF = 1034567891;
const ll LL_INF = 1234567890123456789ll;
const db PI = 3.141592653589793238;
const ldb ERR = 1E-12;
#define mem(x ,y ) memset(x , y , sizeof(x))
struct road{
    int x,y,w ;
}edg[50010];
ll w[105][105] ;
ll d[105][105][105] ;
ll sum[105] ;
const int mod = 1e9+7 ;
int n , m ;
void add(int s,int e,int w,int t){
    for(int z=1;z<=sqrt(w);z++)if(w % z == 0){
        int tmp1 = z , tmp2 = w / z ;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                ll sav1 = t * (d[tmp1][i][s] * d[tmp1][e][j] ) ;
                ll sav2 = t * (d[tmp2][i][s] * d[tmp2][e][j] ) ;
                d[tmp1][i][j] += sav1 ;
                if(tmp1 != tmp2) d[tmp2][i][j] += sav2 ;
                sum[tmp1] += sav1 ;
                if(tmp1 != tmp2) sum[tmp2] += sav2 ;
            }
        }
    }
}
int u[105] ;
int v[105] ;
void init(){
    for(int i=1;i<=100;i++) v[i] = 0 , u[i] = 1 ;
    u[1] = 1 ;
    for(int i=2;i<105;i++)if(!v[i]){
        for(int j=i;j<105;j+=i){
            v[j] = 1 ;
            if(j % (i*i) == 0) u[j] = 0 ;
            else u[j] *= -1 ;
        }
    }
}
int main() {
    init() ;
    cin >> n >> m ;
    for(int i=0;i<m;i++){
        scanf("%d%d%d" , &edg[i].x , &edg[i].y , &edg[i].w) ;
    }
    mem(d , 0) ;
    mem(sum , 0) ;
    ll ans = 0 ;
    for(int x=1;x<=100;x++){
        for(int i=1;i<=n;i++) d[x][i][i] = 1 ;
        for(int t=0;t<m;t++){
            if(edg[t].w % x == 0) d[x][edg[t].x][edg[t].y] ++ ;
        }
        for(int k=1;k<=n;k++){
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++)if(i!=j&&k!=j&&i!=k){
                    d[x][i][j] += d[x][i][k] * d[x][k][j] ;
                    d[x][i][j] %= mod ; 
                }
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++)if(i!=j){
                sum[x] += d[x][i][j] ;
                sum[x] %= mod ; 
            }
        }
        ans += sum[x] * u[x] ;
    }
    cout << ((ans % mod)+mod)%mod << endl ;
    int Q ; cin >> Q ;
    int ta , tb ;
    for(int q=0;q<Q;q++){
        cin >> ta >> tb ; ta -- ;
        int ts = edg[ta].x ; int te = edg[ta].y ;
        add(ts , te , edg[ta].w , -1) ;
        add(ts , te , tb , 1) ;
        edg[ta].w = tb ;
        ans = 0 ;
        for(int i=1;i<=100;i++){
            ans += sum[i] * u[i] ;
        }
        cout << ((ans % mod)+mod)%mod << endl ;
    }
}

用题解的方法还是没过,现在写在这,以后可以看代码,

我用的题解方法。不取mod不超时。取mod就超时。日了狗。以后再看啊

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值