存在
题解区怎么都是二分答案的做法,来一发 VP 时糊出来的更加无脑的模拟做法。
首先假设一圈里有
然后注意其中有一步 __int128_t
。
审核没通过,说太简略了,那么就把具体过程再说一下吧:
维护一个
xxxxxxxxxx
601
2
3
4
5
6
7
8
9
10
11using namespace std;
12
13mt19937 rnd(random_device{}());
14int rndd(int l, int r){return rnd() % (r - l + 1) + l;}
15bool rnddd(int x){return rndd(1, 100) <= x;}
16
17typedef unsigned int uint;
18typedef unsigned long long unll;
19typedef long long ll;
20typedef long double ld;
21
22template < typename T = int >
23inline T read(void);
24
25int N; ll K;
26ll A[210000];
27priority_queue < ll, vector < ll >, greater < ll > > buc;
28
29int main(){
30 N = read(), K = read < ll >();
31 ll cur(0);
32 for(int i = 1; i <= N; ++i)if((A[i] = read < ll >()))buc.push(A[i]), ++cur;
33 ll minus(0);
34 while(!buc.empty()){
35 ll v = buc.top() - minus; buc.pop();
36 if((__int128_t)cur * v <= K)K -= cur * v, minus += v, --cur;
37 else{minus += K / cur, K -= K / cur * cur; break;}
38 }
39 for(int i = 1; i <= N; ++i)A[i] = max(0ll, A[i] - minus);
40 for(int i = 1; i <= N && K; ++i)if(A[i])--A[i], --K;
41 for(int i = 1; i <= N; ++i)printf("%lld%c", A[i], i == N ? '\n' : ' ');
42 fprintf(stderr, "Time: %.6lf\n", (double)clock() / CLOCKS_PER_SEC);
43 return 0;
44}
45
46template < typename T >
47inline T read(void){
48 T ret(0);
49 int flag(1);
50 char c = getchar();
51 while(c != '-' && !isdigit(c))c = getchar();
52 if(c == '-')flag = -1, c = getchar();
53 while(isdigit(c)){
54 ret *= 10;
55 ret += int(c - '0');
56 c = getchar();
57 }
58 ret *= flag;
59 return ret;
60}
update-2023_01_27 初稿
update-2023_02_01 审核没过,将叙述改的更详尽一些