您的位置:首页 > 产品设计 > UI/UE

UVALive - 7715 Guessing Game

2017-07-31 20:11 411 查看
点击打开题目

题意:给出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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  模拟 暴力