C - A Cookie for You【贪心】

if the guest of the second type: if v>c the guest selects a chocolate cookie. Otherwise, the guest selects a vanilla cookie.

```void solve(){
cin >> a >> b >> n >> m;
if(a + b < n + m)    dead();
else{
if(min(a, b) < m)    dead();
else    alive();
}
} ```

D. Grid-00100 【思维】

f(A)=(max(R)−min(R))2+(max(C)−min(C))2

```void solve(){
cin >> n >> k;
if(k % n == 0)    puts("0");
else    puts("2");
int num = k / n;
for(int i = 1; i <= n; ++ i)
for(int j = 1; j <= num; ++ j){
int now = (i + j - 1) % n;
if(!now)    now = n;
mp[i][now] = 1;
}
if(k % n){
int remain = k % n;
for(int i = 1; i <= n && remain; ++ i){
int last = (i + num) % n;
if(!last)    last = n;
mp[i][last] = 1;
remain --;
}
}
for(int i = 1; i <= n; ++ i){
for(int j = 1; j <= n; ++ j)
printf("%d", mp[i][j]), mp[i][j] = 0;
cout << endl;
}
}```

E1. Asterism (Easy Version) && E2. Asterism (Hard Version)【二分+贪心+乘法原理， 好题】

tips:easy&hard只是范围问题， easy中n, a[i] <= 2000, hard中n <= 1e5, a[i] <= 1e9.

```#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int N = 200010;

ll fact[N], a[N];
int n, t, p;

bool check1(int minn){
for(int i = 1; i <= n; ++ i)
if(minn >= a[i])    minn ++;
else return 0;
return 1;
}

//bool check(int mid){
//    int pos = upper_bound(a + 1, a + 1 + n, mid) - a - 1;
//    vector<int> v;
//    for(int i = pos + 1; i <= n; ++ i)
//         if(mp[a[i]] > 1)    v.push_back(fact[mp[a[i]]]), mp[a[i]] = 0;
//    //printf("mid = %d pos = %d\n", mid, pos);
//    int ans = fact[pos];
//    for(auto u : v)    ans = (ll)ans * u % p;
//    return ans;
//}

bool check(int mid){
int ans = 1;
for(int i = n; i >= 1; -- i){
if(a[i] > mid)    ans = (ll)ans * fact[i - a[i] + mid] % p;
else    ans = (ll)ans * fact[i] % p;
}
return ans;
}

void solve(){
cin >> n >> p;
fact[0] = fact[1] = 1;
for(int i = 2; i <= n; ++ i)    fact[i] = fact[i - 1] * i % p;
for(int i = 1; i <= n; ++ i)    scanf("%lld", &a[i]);
sort(a + 1, a + 1 + n);
int minn = a[1], maxx = a[n];
while(minn < maxx){        //先二分求最小值或直接暴力(Easy Verson)求最小值
int mid = (ll)minn + maxx >> 1;
if(check1(mid))        maxx = mid;
else    minn = mid + 1;
}
if(!check(maxx)){
puts("0");
return ;
}
int l = maxx, r = 1e9;
while(l < r){
int mid = l + r + 1 >> 1;
if(check(mid))    l = mid;
else    r = mid - 1;
//printf("l = %d r = %d mid = %d\n", l, r, mid);
}
cout << l - minn + 1 << endl;
for(int i = minn; i <= l; ++ i)    printf("%d ", i);
}

int main(){
//    cin >> t;
//    while(t --)
solve();
return 0;
}```

Tipssss:注意找上界的二分不可以这么贪心（代码中的注释部分）：

```bool check(int mid){
int pos = upper_bound(a + 1, a + 1 + n, mid) - a - 1;
vector<int> v;
for(int i = pos + 1; i <= n; ++ i)
if(mp[a[i]] > 1)    v.push_back(fact[mp[a[i]]]), mp[a[i]] = 0;
//printf("mid = %d pos = %d\n", mid, pos);
int ans = fact[pos];
for(auto u : v)    ans = (ll)ans * u % p;
return ans;
}```