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;}
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- UVALive
- 在使用Git的时候,需要添加tag,这个对版本号非常有用,但是TortoiseGit中在本地打了tag,不知如何提交
- PHP基础教程-07 变量概述
- js行内变量传参,函数内部实参调用
- 我对大数据算法的认知
- for循环删除(ArrayList.remove)报错及解决办法
- UVALive
- [USACO3.2.6]Sweet Butter
- Codeforces Round #426 (Div. 2)B. The Festive Evening
- 在linux系统上安装tomcat
- 水果笔试题
- JVM——锁优化
- linux初学者-虚拟机管理篇
- 浙大版《C语言程序设计(第3版)》题目集前四章总结-续
- python面向对象编程