参考了各路题解。

首先如果一个多边形全部都是一种颜色显然无法分割。

又,我们注意到 $1 \oplus 2 \oplus 3 = 0$。

故一个符合条件的三角形三边颜色异或和为 $0$。

故一个多边形的颜色异或和必须为 $0$ 才能有解。

让我们考虑一次在多边形上分割三角形操作带来的影响,这会使得两种不同颜色的边数量减少 $1$,另一种颜色的边数量增加 $1$,不影响颜色异或和。

考虑我们每一次都只选择两条颜色不一样且数量都不为 $1$ 的边合并。

首先这是一定可以做到的(比较显然)。

然后因为这样分割我们一定不会使得多边形的边都变成同一种颜色(比较显然),又颜色异或和恒为 $0$,所以我们一定可以分割这个多边形。

我们考虑不断查找第一个符合上述合并条件的边,然后与其下一条边合并。

合并完之后,它可能和它的下一条边可以继续合并,所以在上一次操作的位置继续找下去即可。

这样扫在第一次的时候可能有些边无法合并,那么在第二轮扫的时候必定可以合并,否则它是永远无法合并的,这与我们的题设矛盾。

所以一条边最多只会被扫描两次,时间复杂度是 $O(n)$ 的。

可以结合代码思考。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5;
int n;
char s[maxn+5];
int cnt[5],sum;
int nxt[maxn+5],col[maxn+5];
int ansx[maxn+5],ansy[maxn+5],ansc[maxn+5];
signed main(){
scanf("%d",&n);
scanf("%s",s);
for(int i=0;i<n;i++){
nxt[i]=(i+1)%n;
col[i]=s[i]-'0';
cnt[col[i]]++;
sum^=col[i];
}
int x=0,y;
if(cnt[1]==n||cnt[2]==n||cnt[3]==n||sum){
puts("NE");
return 0;
}
for(int t=0;t<n-3;t++){
for(;col[x]==col[nxt[x]]
||(cnt[col[x]]==1&&cnt[col[nxt[x]]]==1);x=nxt[x]);
y=nxt[x];
cnt[col[x]]--;
cnt[col[y]]--;
cnt[col[x]^col[y]]++;
nxt[x]=nxt[y];
col[x]=col[x]^col[y];
ansx[t]=x;
ansy[t]=nxt[x];
ansc[t]=col[x];
}
puts("DA");
for(int t=0;t<n-3;t++)
printf("%d %d %d\n",ansx[t]+1,ansy[t]+1,ansc[t]);
return 0;
}