C Prison(差分)
Description:
给出若干个区间m 请问有多少个点被覆盖了m次
Solution:
差分求解即可
Code:
int c[100005];
signed main()
{
int n, m;
cin >> n >> m;
rep(i, 0, m)
{
int a, b;
cin >> a >> b;
c[a] ++;
c[b + 1] --;
}
int res = 0;
rep(i, 1, n + 1)
{
c[i] += c[i - 1];
if(c[i] == m)
res ++;
}
cout << res << endl;
}
D Integer Cards(贪心 排序)
Description:
给出n个值 给出m组数对(可用次数,值) 可用任意选数对中的值来替换原来值 求替换后最大和
Solution:
贪心地想 最大的值我一定要给他换上 于是结构体排序值大优先 小根堆维护一下n个值 替换即可
Code:
const int N = 100005;
int n, m, x;
struct node {
int val, cnt;
bool operator < (const node &a) const {
return val > a.val;
}
}a[N];
priority_queue<int, vector<int>, greater<int> > q;
signed main()
{
ios;
cin >> n >> m;
rep(i, 1, n + 1)
cin >> x, q.push(x);
rep(i, 1, m + 1)
cin >> a[i].cnt >> a[i].val;
sort(a + 1, a + m + 1);
rep(i, 1, m + 1)
{
for(int j = 0; j < a[i].cnt && a[i].val > q.top(); j ++)
{
q.pop();
q.push(a[i].val);
}
}
LL res = 0;
while(q.size())
{
res += q.top();
q.pop();
}
cout << res << endl;
}
E Cell Distance(枚举 + 排列组合)
Description:
给你三个数 n,m,k,让你在 n∗m 的矩阵中选择 长度为k的正方形
要求计算 在k的正方形中任取2个点的贡献值
Solution:
首先我们预处理出对于整个n*m棋盘任取2个点的总贡献
然后因为我们预处理中是固定两个点来计算贡献 于是其他点的安排就变成了C(n * m - 2, k - 2)
从整个棋盘-2中取k-2个随意排序
Code:
#define int long long
const LL mod = 1e9 + 7;
const int N = 200005;
int fac[N], inv[N];
int n, m, k;
int qpow(int a, int b)
{
int res = 1;
while(b)
{
if(b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
void init()
{
fac[0] = 1;
for(int i = 1; i <= N - 5; i ++)
fac[i] = fac[i - 1] * i % mod;
inv[N - 5] = qpow(fac[N - 5], mod - 2);
for(int i = N - 6; i >= 0; i --)
inv[i] = inv[i + 1] * (i + 1) % mod;
}
int C(int a, int b)
{
return fac[a] * inv[b] % mod * inv[a - b] % mod;
}
signed main()
{
ios;
init();
cin >> n >> m >> k;
int res = 0;
//枚举一下摆放的情况 每次枚举列间距
for(int i = 1; i < m; i ++)
res = (res + (m - i) * i % mod * n % mod * n % mod) % mod;
//枚举行间距
for(int i = 1; i < n; i ++)
res = (res + (n - i) * i % mod * m % mod * m % mod) % mod;
res = res * C(n * m - 2, k - 2) % mod;
cout << res << endl;
}