C. Ayoub and Lost Array cf dp

C. Ayoub and Lost Array

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

Ayoub had an array aa of integers of size nn and this array had two interesting properties:

  • All the integers in the array were between ll and rr (inclusive).
  • The sum of all the elements was divisible by 33 .

Unfortunately, Ayoub has lost his array, but he remembers the size of the array nn and the numbers ll and rr , so he asked you to find the number of ways to restore the array.

Since the answer could be very large, print it modulo 109+7109+7 (i.e. the remainder when dividing by 109+7109+7 ). In case there are no satisfying arrays (Ayoub has a wrong memory), print 00 .

Input

The first and only line contains three integers nn , ll and rr (1≤n≤2?105,1≤l≤r≤1091≤n≤2?105,1≤l≤r≤109 ) — the size of the lost array and the range of numbers in the array.

Output

Print the remainder when dividing by 109+7109+7 the number of ways to restore the array.

Examples

Input

Copy

2 1 3

Output

Copy

3

Input

Copy

3 2 2

Output

Copy

1

Input

Copy

9 9 99

Output

Copy

711426616

Note

In the first example, the possible arrays are : [1,2],[2,1],[3,3][1,2],[2,1],[3,3] .

In the second example, the only possible array is [2,2,2][2,2,2] .

这个题目先要意识到这是一个动态规划

他是在范围内取一个元素个数为n,对3的余数为0的集合的方案数。

这个就可以当初一种动态规划,从1到n转移。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+100;
ll mod=1e9+7,dp[maxn][4];//dp[i][j]代表余数为j时,集合元素为i的方案数

int main()
{
    int n,l,r,a=0,b=0,c=0;
    cin>>n>>l>>r;
    int k=(r-l)/3;
    a=b=c=k;
    for(int i=l+3*k;i<=r;i++)
    {
        if(i%3==0) a++;
        if(i%3==1) b++;
        if(i%3==2) c++;
    }
    dp[1][0]=a;
    dp[1][1]=b;
    dp[1][2]=c;
    for(int i=2;i<=n;i++)
    {
        dp[i][0]=dp[i-1][0]*a%mod;
        dp[i][0]%=mod;
        dp[i][0]+=dp[i-1][1]*c%mod;
        dp[i][0]%=mod;
        dp[i][0]+=dp[i-1][2]*b%mod;
        dp[i][0]%=mod;
        dp[i][1]=dp[i-1][0]*b%mod;
        dp[i][1]%=mod;
        dp[i][1]+=dp[i-1][1]*a%mod;
        dp[i][1]%=mod;
        dp[i][1]+=dp[i-1][2]*c%mod;
        dp[i][1]%=mod;
        dp[i][2]=dp[i-1][0]*c%mod;
        dp[i][2]%=mod;
        dp[i][2]+=dp[i-1][1]*b%mod;
        dp[i][2]%=mod;
        dp[i][2]+=dp[i-1][2]*a%mod;
        dp[i][2]%=mod;
    }
    cout<<dp[n][0]<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/EchoZQN/p/10357249.html

时间: 2024-08-06 08:23:51

C. Ayoub and Lost Array cf dp的相关文章

Codeforces Round #533 (Div. 2)C. Ayoub and Lost Array

C. Ayoub and Lost Array Ayoub had an array ?? of integers of size ?? and this array had two interesting properties: All the integers in the array were between ?? and ?? (inclusive). The sum of all the elements was divisible by 3. Unfortunately, Ayoub

CF1105C Ayoub and Lost Array ——动态规划

CF1105C Ayoub and Lost Array 题意:一个整数数组,满足: 1. 长度为n 2. 所有元素都在[l, r]范围内 3. 所有元素的和能被3整除给出n, l, r (1 ≤ n ≤ 2*10^5,1 ≤ l ≤ r ≤ 10^9)请找出符合条件的数组的个数,答案对 10^9 + 7取模 首先我们要处理出[l, r]中对3取模得结果分别为0,1,2的数的个数,在一个合乎要求的数组中,结果为1和2的数的个数必然一样,由此就可以很方便地得到所有可能的组合的个数.但新的问题来了,

【HDOJ 5653】 Bomber Man wants to bomb an Array.(DP)

[HDOJ 5653] Bomber Man wants to bomb an Array.(DP) Bomber Man wants to bomb an Array. Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 389    Accepted Submission(s): 117 Problem Description Give

HDU5280 Senior&#39;s Array(简单DP)

题目链接:传送门 题意: 给定一个长度为n的序列,和一个修改的值p,必须从原序列中选一个位置修改成p, 求修改后的区间和的最大值. 分析: 枚举位置+最大区间和.复杂度O(n^2); 代码如下: #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; typedef long long LL; const int ma

C. Ayoub and Lost Array Round #533 (Div. 2) 【DP】

一.题面 链接 二.分析 关于这题,两个点. 第一个点,是需要能够分析出$[L,R]$区间的3的余数的个数. 首先,可以得到,$[L,R]$区间内共有$(R-L+1)$个数. 设定余数为0,1,2的为一组,那么1,2,0和2,0,1也是一组.那么可以肯定能得到$(R-L+1)/3$组. 那么还余下了$(R-L+1)%3$个数.这里就需要考虑从$L$开始往右移$(R-L+1)%3$个数,分析这几个数的余数即可.因为这几个数后的数肯定是能分成3个一组的. 第二个点,用DP的思维去求解. 区间内的数能

codeforces round 533 div2 C Ayoub and Lost Array [dp]

一道思维题 不仅是和这道题在战斗,我和编译器也进行了一场激烈的角逐 因为编译器出了点小问题... 对于dev或者codeblocks 我的方法是卸载了重新装/重启电脑 但是对于vscode 我的方法是, 对着它掉眼泪,看它能不能可怜可怜我,赶紧恢复到正常状态.... #include<bits/stdc++.h> using namespace std; typedef long long ll; //#define int long long const ll N = 2e5 + 1000;

【Coder Force】#360B - Levko and Array(DP 二分枚举)

题目大题:CF上的题目还是比较容易读懂的.这道题的意思嘛,他是说,有一个不超过2000个数的数组,每一个数与后面的数的绝对值称为value,那么所有当中最大的value就是整个数组的value,现在你有k次变换,每一次可以将其中的一个数变为任何一个使得数组价值最小的数. 假如题目的价值是所有的之和,也可以用这道题的方法. 思路: dp[i]表示的是到i这个位置,使得数组符合条件的最少变换次数. 这个符合条件就奇妙了,这个符合条件是由你定的,最终的符合条件就是答案. 简单来说:你举例一个答案,放进

CF dp 一句话解题

wyq说刚入门oi 或是遇到瓶颈的时候就刷DP吧,虽然觉得这么刷CF题有点浪费,但是还是挺爽的,按照solved排序做的,前面的题都挺水的(忘记记录了混蛋),就不写了,从5C开始写解题 CF5 C. Longest Regular Bracket Sequence:题目大意,给一个括号序列,让你求最长的合法扩号子串,以及最长子串出现的次数 思路:开个栈乱搞,当遇到右括号的时候这右括号开始最长的长度应该是到左括号的长度加上左括号左边一个字符的最长长度

HDU5653 Bomber Man wants to bomb an Array 简单DP

题意:bc 77 div1 1003(中文题面) 分析:先不考虑将结果乘以 1e6. 设 dp[i] 为从前 i 个格子的状态可以获得的最大破坏指数. 那么我们可以枚举每个炸弹,该炸弹向左延伸的距离和向又延伸的距离. 设第 i 个炸弹破坏区间为 [l, r], 则 dp[r] = dp[l - 1] + log2(r - l + 1).答案就是 dp[n - 1].不要忘记最后要向下取整. 注:我对官方题解稍作解释,dp[i]代表前i个格子可以获得的最大破坏指数 但是更新的时候,需要注意,假设有