UVALive

来源:互联网 发布:正品潮牌代购淘宝店 编辑:程序博客网 时间:2024/06/03 22:40

点击打开题目


题意:给出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;}



原创粉丝点击