数论+快速幂 SRM 661 Div1 450: ColorfulLineGraphs

http://community.topcoder.com/stat?c=problem_statement&pm=13765

Problem Statement

Bob is going to create a graph with N nodes. The graph will be constructed in two steps. First, Bob will take N isolated vertices, label them 1 through N and color each of them using one of K colors. Then, Bob will add some directed edges to the graph. For each i between 2 and N, inclusive, Bob may choose a single value j < i such that the nodes i and j have different colors. If he does, he will add the edge from i to j to his graph. Note that Bob may choose not to add any edge from node i, even if there are some valid choices of j.

Two graphs are considered the same if they have the same node colors and the same set of edges.

You are given the longs N and K. You are also given an int M. Compute and return the number of different graphs Bob may construct, modulo M.

Definition

  • ClassColorfulLineGraphs
  • MethodcountWays
  • Parameterslong long , long long , int
  • Returnsint
  • Method signatureint countWays(long long N, long long K, int M)
(be sure your method is public)

Limits

  • Time limit (s)2.000
  • Memory limit (MB)256

Constraints

  • N will be between 1 and 1,000,000,000,000 (10^12), inclusive.
  • K will be between 1 and 1,000,000,000,000 (10^12), inclusive.
  • M will be between 2 and 1,000,000 (10^6), inclusive.

Test cases

    • N3
    • K2
    • M100000
    Returns24

    The 24 different graphs are shown below. In each picture, the vertices have labels 1, 2, 3 from the left to the right.

    • N15
    • K3
    • M1000000
    Returns510625
    • N100000
    • K100000
    • M999999
    Returns185185
    • N1000000000000
    • K6
    • M1000000
    Returns109376
    • N5000
    • K1000000000000
    • M314159
    1. Returns202996

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1. 题解
  2. The constraints, except for M are much larger than in the division 2 version. It is interesting M remains relatively small, as if O(M) or similar was intended. The large constraints for N and K suggest we might need to get creative, however.

    Imagine we are deciding what to do for the nodes in order from left to right (lowest index to highest). Imagine we already made decisions for the first i nodes. We know their colors and we know which edges (or lack of) we picked for each of them. Remember (from division 2) that when assigning things to do with the higher nodes, we only need to remember the number of nodes of each color that have been assigned, we don't need to know the edges. Let's count the number of decisions for node # i:

    • We may decide to use color #0. Then we have to pick an edges. We can pick no edge at all or we can connect node i to any node of a color different than 0. in which case we have 1+(icount(i,0)) options, where count(i,0) is the number of nodes of color 0 among the first i nodes.
    • For color 1: 1+icount(i,1).
    • ...
    • For color + k11+icount(i,k1).

    What happens if we add together all the options?

    1+icount(i,0)
    +1+icount(i,1)
    +1+icount(i,2)
    +...
    +1+icount(i,k1)

    k times 1, k times i and the sum of all counts:

    k+kij=0j<k(count(i,j))

    This is the interesting part: What is j=0j<k(count(i,j)) ? The sum of all the counts of colors among the first i nodes. This will be always equal to i. There are i nodes in total and the sum of all counts for each color will always be i. This means that the number of options for node i is: k+kii=k+i(k1). So in fact, the color choices before i are not relevant for the final result, only the total number of available colors. This way we can have an O(N) formula, just multiply k+i(k1) for each i : i=0i<N(i(k1)+k)

    N is still too large even for an O(N) so we need more improvements. This is where the small constraints on M can come into play. From i=0, to N1, the value imodM behaves in a cycle. So imagine M=3. For i=0,1,2,3,4,5,6,7, the values of imod3 will be: 0,1,2,0,1,2,0,1. Remember that (ab)modM=((amodM)(bmodM))modM, so i=0i<N(i(k1)+k)modM is equal to: i=0i<N((i(k1)+k)modM). Each (i(k1)+k)modM depends solely on i, more specifically imodM:

    (i(k1)+k)modM(((imodM)(k1)modM)+(kmodM))

    The only non-constant part is imodM. This part is cyclic and repeats every M parts. So back to the N=7,M=3 example: i=0,i=3,i=6 all will yield the same value of (i(k1)+k)modM. We can say the same about i=1,i=4 and i=2,i=5. We just need to use this cycle to our advantage.

    So for simplicity, let's name g(i)=(i(k1)+k)modM. We need to calculate:

    (g(0)g(1)g(2)...g(N1))modM

    We have the knowledge that for every pair ijmodMg(i)g(j)modM (The values of g(i) are repeated every M times). So imagine this:

    (g(0)g(1)g(2)...g(M1)g(M)g(M+1)g(M+2)...g(2M1)...g((N/M)1)
    g((N/M)M)g((N/M)M+1)...g((N/M)M+(NmodM)1)modM

    What we have here is the same M values are repeated over and over again, the first M values, the next M values and so and so. They will be repeated (N/M) times (integer, round down division). There will be some extra values depending if M divides N evenly. NmodM additional values (The remainder).

    (g(0)g(1)g(2)...g(M1)g(0)g(1)g(2)...g(M1)...g(0)g(1)g(2)...g(M1)
    g(0)g(1)...g((NmodM)1)modM

    The product g(0)g(1)g(2)...g(M1) is repeated exactly N/M times. So we can actually calculate the product of the first (N/M)M values by using the following:

    (g(0)g(1)g(2)...g(M1))N/M

    This requires O(M) time to calculate the product of the first M values, then we can use O(log(N/M)) time to calculate the power (for example, using exponentiation by squaring).

    Finally we need to multiply that to: g(0)g(1)...g((NmodM)1), This requires O(M) further steps. In total we have an O(O(log(N/M))+M) algorithm:

    long mod_pow(long x, long y, long M)
    {
        //exponentiation by squaring:
        long r = 1;
        long a = x;
        while (y > 0) {
            if (y % 2 == 1) {
                r = (r * a) % M;  
            }
            a = (a * a) % M;
            y /= 2;
        }
        return r;
    }
     
    int countWays(long N, long K, int M)
    {
        long p = 1, q = 1;
        // p will store product of all i < M
        // q will store product of all i &ly; N%M
        for (int i = 0; i < M; i++) {
            long x = (i*(K - 1) + K) % M;
            p = (p * x) % M;            
            if (i < N%M) {
                q = p;
            }
        }
        return (mod_pow(p, N/M, M) * q) % M;
    }

    看完有没有很爽的感觉^-^


内容概要:本文介绍了一个关于三相桥式全控整流及有源逆变电路的实验仿真模型,重点研究三相整流器与逆变器在Simulink环境下的建模与仿真技术。内容涵盖电力电子变换器的工作原理、控制策略设计、系统动态响应分析,并进一步扩展至10kV配电网中不同中性点接地方式(中性点不接地、经小电阻接地、经消弧线圈接地)下的单相、两相短路接地及相间短路故障的仿真研究,全面呈现了电力系统典型故障的暂态特性。此外,文档还整合了丰富的科研资源,涵盖电力系统优化、新能源并网、故障诊断、微电网调度等多个前沿方向,充分体现了Matlab/Simulink在电气工程仿真中的核心地位和广泛应用价值。; 适合人群:电气工程、自动化、电力电子等相关专业的高校学生、科研人员及工程技术人员,具备一定的电路理论基础和仿真软件操作经验者更佳。; 使用场景及目标:①用于教学实验中帮助理解三相整流与逆变电路的工作机制;②支撑科研项目中对电力系统故障特性的建模与分析;③作为开发新型控制算法(如PWM控制、低电压穿越等)的仿真验证平台;④辅助完成毕业设计、课题研究或工程方案评估; 阅读建议:此资源以Simulink仿真实现为核心,强调理论与实践结合,建议读者在学习过程中同步搭建模型,动手调试参数,深入理解各模块功能与系统整体行为,同时可参考文中提供的完整资源链接拓展研究视野。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值