UVALive - 7715 Guessing Game

3 篇文章 0 订阅
1 篇文章 0 订阅

点击打开题目


题意:给出A1,A2,B1,B2,C1,C2,N,问有多少种方法使得A1<=A<=A2,B1<=B<=B2,C1<=C<=C2且A+B+C=N

 

分析:要使A+B+C = N,即求A+B = N-C有多少种解法,那么N-C有一个取值范围[l, r],且这个区间的一个值唯一对应一个C值,那么现在就是求A+B = K(K = N-C)有多少种取值了

先看这样一个例子, A1 = 0, A2 = 2,B1 = 1, B2 = 6的情况,对于[A1, A2]每个值加上B的值的情况如下

A=0     A=1     A=2   对应的和     对应的和的AB的取法

 

              8        8          1

        7     7        7          2

 6      6     6        6          3

 5      5     5        5          3

 4      4     4        4          3

 3      3     3        3          3

 2      2              2          2

 1                     1          1

 可以发现,在[A1+B1,A2+B1)之间,对应的和的取法为等差数列,且公差为1,在[A2+B1, A1+B2]之间,对应的和的取法不变,在(A1+B2,A2+B2]之间,对应的和的取法为等差数列,公差为-1,暴力枚举各个区间就可以了...

 

注意: 如果数据量比较小, 用FFT求解会更简便.

#include<bits/stdc++.h>
typedef long long ll;
const int maxn = 3e3 + 10;
const ll mod = 1e9 + 7;
using namespace std;

ll qmod(ll a, ll b) {
    ll ans = 1;
    while(b) {
        if(b & 1) ans = ans * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ans;
}

int T, kase = 1;
ll A1, A2, B1, B2, C1, C2, N;

int main() {
    scanf("%d", &T);
    while(T--) {
        scanf("%lld %lld %lld %lld", &A1, &A2, &B1, &B2);
        scanf("%lld %lld %lld", &C1, &C2, &N);
        if(B2 - B1 < A2 - A1) { swap(A1, B1); swap(A2, B2); }
        ll L1 = A1 + B1, L2 = A2 + B1;
        ll L3 = B2 + A1, L4 = A2 + B2;
        ll L = N - C2, R = N - C1;
        ll ans = 0;
        ll a1 = ((L2 - L1) * (L2 - L1 + 1) % mod) * qmod(2, mod - 2) % mod;
        ll a2 = (L3 - L2 + 1) * (A2 - A1 + 1) % mod;
        ll a3 = a1;
        if(L > L4 || R < L1) ans = 0;
        else if(L < L1) {
            if(R >= L1 && R < L2) {
                ans = ((R - L1 + 1) * (R - L1 + 2) % mod) * qmod(2, mod - 2) % mod;
            } else if(R >= L2 && R <= L3) {
                ans = a1 % mod;
                ans = (ans + (R - L2 + 1) * (A2 - A1 + 1) % mod) % mod;
            } else if(R > L3 && R <= L4) {
                ans = (a1 + a2) % mod;
                ans = ((ans + a3 - ((L4 - R) * (L4 - R + 1)) % mod * qmod(2, mod - 2)) + mod) % mod;
            } else {
                ans = (a1 + a2 + a3) % mod;
            }
        } else if(L >= L1 && L < L2) {
            if(R < L2) {
                ll aa1 = (L - L1 + 1) % mod;
                ll n = (R - L + 1) % mod;
                ans = (n * aa1 + (n * (n - 1) % mod) * qmod(2, mod - 2)) % mod;
            } else if(R >= L2 && R <= L3) {
                ll aa1 = (L - L1 + 1) % mod;
                ll n = (L2 - L) % mod;
                ans = (n * aa1 + (n * (n - 1) % mod) * qmod(2, mod - 2)) % mod;
                ans = (ans + (R - L2 + 1) * (A2 - A1 + 1) % mod) % mod;
            } else if(R > L3 && R <= L4) {
                ll aa1 = (L - L1 + 1) % mod;
                ll n = (L2 - L) % mod;
                ans = (n * aa1 + (n * (n - 1) % mod) * qmod(2, mod - 2)) % mod;
                ans = (ans + a2) % mod;
                ans = ((ans + a3 - ((L4 - R) * (L4 - R + 1) % mod * qmod(2, mod - 2))% mod ) % mod + mod ) % mod;
            } else {
                ll aa1 = (L - L1 + 1) % mod;
                ll n = (L2 - L) % mod;
                ans = (n * aa1 % mod + (n * (n - 1) % mod) * qmod(2, mod - 2)) % mod;
                ans = (ans + a2) % mod;
                ans =(ans + a3) % mod;
            }
        } else if(L >= L2 && L <= L3) {
            if( R <= L3) {
                ans = (R - L + 1) * (A2 - A1 + 1) % mod;
            } else if(R > L3 && R <= L4) {
                ans = (L3 - L + 1) * (A2 - A1 + 1) % mod;
                ans = (ans + a3 - ((L4 - R) * (L4 - R + 1) % mod) * qmod(2, mod - 2) + mod) % mod;
            } else {
                ans = (L3 - L + 1) * (A2 - A1 + 1) % mod;
                ans = (ans + a3) % mod;
            }
        } else if(L > L3 && L <= L4){
            if(R <= L4) {
                ll aa1 = (L4 - R + 1) % mod;
                ll n = (R - L + 1) % mod;
                ans = (n * aa1 % mod + (n * (n - 1) % mod) * qmod(2, mod - 2)) % mod;
            } else {
                ans = ((L4 - L + 2) * (L4 - L + 1) % mod) * qmod(2, mod - 2) % mod;
            }
        }
        printf("Case #%d: %lld\n", kase++, ((ans % mod) + mod) % mod);
    }
    return 0;
}



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值