Problems: https://codeforces.com/contest/1416 or https://www.luogu.com.cn/problem/list?keyword=CF1416
Solution
Div2 A.Copy-paste
签到题 一直用最小的加就好了
你可能会疑惑最小的就那么放掉会不会有点浪费
考虑最小和次小互相加的情形,更浪费了。
10min
Div2 B.Two Arrays
把一个 Array 分成两部分,要求[每部分里(相加等于 T 的数对个数)]的和最小。
这也是道签到题。值等于 (frac{T}{2}) 的对半分呐。
剩下的,小于的两两相加一定不等于,大于的两两相加一定不等于。
不要读错题就可以了。也不要犯傻排序了再去取个中间值再搞来搞去。
20min
A.k-Amazing Numbers
一个 Array 的 kAN 是指最小的,在该 Array 的所有长度为 k 的 Subsegments 里都出现的数
如果没有这种数就是-1
。请 (O(nlog{n})) 计算 1AN ~ nAN
读完题就可以 Accepted
稍微模拟一下。然后我也不知道为啥我做了这么久。
30min
B.Make Them Equal
(1le i,jle n,quad 0le xle10^9)
每次操作:选择三元组 ((i,j,x)) 使 (a_i) 减去 (xcdot i) ,而 (a_j) 加上 (xcdot i)
请在 (3n) 次操作内使长为 (n) 的序列 (a) 中每个元素相等。过程中不得出现负数。
(1le nle10^4,quad 1le a_ile10^5)
找到任意一种方案即可。请输出 (k) 的值 和 这 (k) 次操作。如果不能,请输出-1
。
这题比较 interesting
(x) 可以自由选择。 (i) 和 (j) 也可以自由选择,甚至可以一样(
很显然,假如 (i=1) 并且 (a_1) 足够大,那么可以随便挑一个 (a_i) 出来随便赋值
但是 (i>1) 就不行了。
从条件思考一下,为什么是 (3n) ?
假如已经满足 (i=1) 并且 (a_1) 足够大(应当为 (n) 的倍数),我们仍然需要 n 次操作让后面的数全部一样。
这个操作貌似不会改变 (sum a_i) ?
那完全可以把所有数挪到 (a_1) 再慢慢分配过去啊。同时可行性也能够直接判断了。
好吧。怎么挪?如果 (i|a_i) 那很简单
否则就得先凑到 (i|a_i)。从 (a_1) 那里拿过来凑就行了。
(a_1) 那里一定有吗?不一定
所以 (i) 从 (2) 开始枚举到 (n) 就可以了。(a_ige0) 啊。
这样的话,最多就是凑+挪+挪回去,对于所有大于 1 的数最多操作 3 次
所以总的操作次数不超过 (3n-3)
我深刻地感觉我不能再依赖博客写题了 速度过慢
40min
Wa 了两三发。
务必注意一定要最后再把所有数从 1 分配过去
否则可能 1 的位置中途会出现负数。
C.XOR Inverse
D.Graph and Queries
E.Split
F.Showing Off
Code
Code: Div2A.
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iomanip>
#include<set>
#include<vector>
#include<map>
#include<queue>
using namespace std;
const int MAXN = 1005;
int T, n, k, Minn, id;
int a[MAXN], Ans;
int main()
{
cin >> T;
while (T--)
{
cin >> n >> k;
Minn = 214748;
Ans = 0;
for (int i = 1; i <= n; ++i)
{
cin >> a[i];
if (a[i] < Minn)
{
Minn = a[i];
id = i;
}
}
for (int i = 1; i <= n; ++i)
{
if (i != id) Ans += (k - a[i]) / Minn;
}
cout << Ans << endl;
}
return 0;
}
Code: Div2B.
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
const int MX = 1e5+10;
int t, N, T;
bool bel;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> t;
while (t--)
{
cin >> N >> T;
for (int a, c = 0, i = 1; i <= N; ++i)
{
cin >> a; bel = 0;
if ((a<<1) < T) bel = true;
if ((a<<1) == T) bel = (c++)&1;
cout << bel << ' ';
} cout << endl;
}
return 0;
}
Code: A.
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
const int MAXN = 3e5 + 10;
int t, n;
int LastVis[MAXN];
int Filled[MAXN];
int Min[MAXN];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> t;
while (t--)
{
cin >> n;
for (int i = 1; i <= n; ++i) LastVis[i]=0, Min[i]=-1;
for (int a, i = 1; i <= n; ++i)
{
cin >> a;
Min[a] = max(Min[a], i-LastVis[a]);
LastVis[a] = i;
Filled[i] = 0;
}
for (int i = 1; i <= n; ++i)
{
Min[i] = max(Min[i], n + 1 - LastVis[i]);
}
for (int i = 1; i <= n; ++i)
{
if (Min[i]==-1) continue;
if (!Filled[Min[i]]) Filled[Min[i]] = i;
}
for (int Laa = 0x3f3f3f3f, Lst = -1, i = 1; i <= n; ++i)
{
if (Filled[i] && Filled[i] < Laa) Lst = Filled[i], Laa = Filled[i];
cout << Lst << " ";
}
cout << endl;
}
return 0;
}
Code: B.
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
using namespace std;
const int MAXN = 1e4 + 10;
int t, n, tot = 0;
int a[MAXN], sm;
struct opt
{
int i, j, x;
opt(int a=0, int b=0, int c=0)
{
i=a; j=b; x=c;
}
}grp[MAXN*3];
int main()
{
cin >> t;
while (t--)
{
tot = 0;
cin >> n;
cin >> a[1];
sm = a[1];
for (int i = 2; i <= n; ++i)
{
cin >> a[i];
sm += a[i];
}
if (sm%n)
{
puts("-1");
continue;
}
sm /= n;
for (int tmp, i = 2; i <= n; ++i)
{
tmp = a[i]/i;
if (a[i]==tmp*i)
{
grp[++tot]=opt(i, 1, tmp);
}
else
{
grp[++tot]=opt(1,i,(tmp+1)*i-a[i]);
grp[++tot]=opt(i,1,tmp+1);
}
}
for (int i = 2; i <= n; ++i)
{
grp[++tot]=opt(1,i,sm);
}
cout << tot << endl;
for (int i = 1; i <= tot; ++i)
{
cout << grp[i].i << " " << grp[i].j << " " << grp[i].x << endl;
}
}
return 0;
}
Code: C.
Code: D.
Code: E.
Code: F.