The meaning of the question is to give a set of numbers. There is an operation that can select two numbers $A[i],A[j]$. For one of them $+1$ and the other $-1$, ask the minimum number of operations to make these numbers $Max-Min<=K$.
Violence. . . Record the maximum value and the number and position of the minimum value.
int n,k; int val[maxn]; int hax[maxn]; voidsolve() { sa(n),sa(k); int maxx=0,minn=1e5; repp(i,1,n) { sa(val[i]); hax[val[i]]++; minn=min(minn,val[i]); maxx=max(maxx,val[i]); } int cnt=0; while(true) { if(abs(maxx-minn)<=k)break; int num=min(hax[minn],hax[maxx]); cnt+=num; //DE(maxx) //DE(minn) hax[minn]-=num; hax[maxx]-=num; if(hax[minn]==0) { minn++; hax[minn]+=num; } else { hax[minn+1]+=num; } if(hax[maxx]==0) { maxx--; hax[maxx]+=num; } else { hax[maxx-1]+=num; } } cout<<cnt<<endl; }
D.Odd Palindromes
A string is odd palindromic, which means that all its odd substrings are palindromes. Now given a string that can be modified $K$ times at most, ask what is the longest odd palindromic length that can be achieved.
I found that odd palindromic is ABABA… in this form.
Then modify ZZZPROTECT 11ZZZ times at most. You can record the values of odd positions and even positions respectively, using double pointers. $O(n)$.
boolcheck() { int sum1 = 0, sum2 = 0; int maxx1 = 0, maxx2 = 0;
for (int i = 0; i<26; i++) { sum1 += num[0][i]; maxx1 = max(maxx1, num[0][i]); }
int sur = k - (sum1 - maxx1);
for (int i = 0; i<26; i++) { sum2 += num[1][i]; maxx2 = max(maxx2, num[1][i]); } sur = sur - (sum2 - maxx2);
if (sur<0)returnfalse; elsereturntrue; }
voidsolve() { sa(k); scanf("%s", val + 1); int len = strlen(val + 1);
int en = 0; int res = 1; int flag = 0; for (int i = 1; i <= len; i++) { int flag = 0; while (true) { if (!check()) { flag = 1; break; } if (en >= len) { flag = 2; break; } num[(en+1) & 1][val[en+1] - 'a']++; en++; } if (flag == 1) res = max(res, en - i); else res = max(res, en - i + 1); num[i&1][val[i] - 'a']--; } printf("%d\n", res); }
E.Root Change
There is a tree with $N(N<10^5)$ nodes. Now the $i$th query is how many edges can be deleted without affecting the depth of the tree when the $i$th point becomes the root of the tree.
First, if the root node is determined, then the LCA chain from the root to the deepest leaf node needs to be maintained, and the depth of the tree and the number on the link node need to be recorded.
Now each node is required to be the root. Considering transfer, a node can know the chain of its down through dfs, and the up value can be obtained by recording the suffix and prefix values of its parent node on the child node.
int n; int vis[maxn]; int ans[maxn]; vector<int>edge[maxn];
structHei { int h; int num; Hei() {}; Hei(int x, int y) { h = x; num = y; } voidmerge(const Hei &b) { if (b.h>h) { h = b.h; num = b.num; } elseif (b.h == h) { num = 0; } } Hei Go_up() { returnHei(h + 1, num + 1); } };
Hei up[maxn], down[maxn];
voidcal(int x) { vis[x] = 1; down[x] = Hei(0, 0); for (int i = 0; i<edge[x].size(); i++) { int nxt = edge[x][i]; if (vis[nxt])continue; cal(nxt); down[x].merge(down[nxt].Go_up()); } vis[x] = 0; }
voidcalDown(int x) { Hei suf(0, 0); vis[x] = 1; for (int i = edge[x].size() - 1; i >= 0; i--) { int nxt = edge[x][i]; if (vis[nxt])continue; up[nxt] = suf; suf.merge(down[nxt].Go_up()); } Hei pre(0, 0); for (int i = 0; i<edge[x].size(); i++) { int nxt = edge[x][i]; if (vis[nxt])continue; Hei h = up[x]; h.merge(pre); h.merge(up[nxt]); up[nxt] = h.Go_up(); pre.merge(down[nxt].Go_up()); calDown(nxt); } pre.merge(up[x]); ans[x] = pre.num; vis[x] = 0; }