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 has lost his array, but he remembers the size of the array ? and the numbers ? and ?, 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+7 (i.e. the remainder when dividing by 109+7). In case there are no satisfying arrays (Ayoub has a wrong memory), print 0. Input The first and only line contains three integers ?, ? and ? (1≤?≤2⋅105,1≤?≤?≤109) — the size of the lost array and the range of numbers in the array. Output Print the remainder when dividing by 109+7 the number of ways to restore the array. Examples input 2 1 3 output 3 input 3 2 2 output 1 input 9 9 99 output 711426616 Note In the first example, the possible arrays are : [1,2],[2,1],[3,3]. In the second example, the only possible array is [2,2,2].

dp第一维枚举已经取的位数,第二维表示模3的余数:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#define INF 0x3f3f3f3f
#define ll long long
#define ull unsigned long long
#define lowbit(x) (x&(-x))
#define eps 0.00000001
#define PI acos(-1)
#define pn printf("\n");
using namespace std;

int mod = 1e9+7;
const int maxn = 2e5+5;
ll dp[maxn][3];
int n;

void solve(ll c0, ll c1, ll c2)
{
    dp[1][0] = c0;
    dp[1][1] = c1;
    dp[1][2] = c2;
    for(int i = 2; i <= n ;i++)
    {
        dp[i][0] = (dp[i-1][1] * c2 % mod + dp[i-1][2] * c1 % mod + dp[i-1][0] * c0 % mod) % mod;
        dp[i][1] = (dp[i-1][1] * c0 % mod + dp[i-1][2] * c2 % mod + dp[i-1][0] * c1 % mod) % mod;
        dp[i][2] = (dp[i-1][1] * c1 % mod + dp[i-1][2] * c0 % mod + dp[i-1][0] * c2 % mod) % mod;
    }
    
}

int main()
{
    ll l, r;
    scanf("%d%lld%lld", &n, &l, &r);
    ll uni = (r - l + 1) / 3;
    ll res = (r - l + 1) % 3;
    ll c0 = 0, c1 = 0, c2 = 0;
    if(l % 3 == 0)
    {
        c0 = uni + (res >= 1);
        c1 = uni + (res >= 2);
        c2 = uni;
    }
    else if(l % 3 == 1)
    {
        c0 = uni;
        c1 = uni + (res >= 1);
        c2 = uni + (res >= 2);
    }
    else
    {
        c0 = uni + (res >= 2);
        c1 = uni;
        c2 = uni + (res >= 1);
    }
    solve(c0, c1, c2);
    printf("%lld\n", dp[n][0]);
}

 

转载于:https://www.cnblogs.com/HazelNut/p/10298095.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值