这次是中国大佬出题,结果被虐惨了。
A. Nauuo and Votes

1 #include<bits/stdc++.h> 2 #define Rint register int 3 using namespace std; 4 typedef long long LL; 5 int x, y, z; 6 int main(){ 7 scanf("%d%d%d", &x, &y, &z); 8 if(x + z - y < 0) puts("-"); 9 else if(x - y - z > 0) puts("+"); 10 else if(x == y && z == 0) puts("0"); 11 else puts("?"); 12 }
B. Nauuo and Chess

1 #include<bits/stdc++.h> 2 #define Rint register int 3 using namespace std; 4 typedef long long LL; 5 int n, m; 6 int main(){ 7 scanf("%d", &n); 8 m = (n >> 1) + 1; 9 printf("%d ", m); 10 for(Rint i = 1;i <= m;i ++) 11 printf("%d %d ", 1, i); 12 for(Rint i = 2;i <= n - m + 1;i ++) 13 printf("%d %d ", i, m); 14 }
C. Nauuo and Cards
(乱搞能力有待加强)
首先我们分两种情况,手上会拿到1和不会拿到1.
对于后者,初始的时候1要在队列中并且它之后是$2,3,4,ldots,i-1$,然后之后可以把$i,i+1,ldots,n$放进队列中,需要$n-i+1$步。
对于前者,用$p_i$表示$i$初始在队列的位置,不在则为0,也就是至少$p_i$步之后可以拿到这张牌,将$i$从$p_i$这个位置转移到$i$需要$p_i-i+n+1$步,取最大值即为答案。
感性理解:首先如果后者可以那么后者一定比前者更优,对于前者,我们可以通过先扔一些空牌来拿到足够的牌,然后依次把$1,2,3,ldots n$扔出去,不会更优。

1 #include<bits/stdc++.h> 2 #define Rint register int 3 using namespace std; 4 const int N = 200003; 5 int n, a[N], b[N], p[N], ans; 6 int main(){ 7 scanf("%d", &n); 8 for(Rint i = 1;i <= n;i ++){ 9 scanf("%d", a + i); p[a[i]] = 0; 10 } 11 for(Rint i = 1;i <= n;i ++){ 12 scanf("%d", b + i); p[b[i]] = i; 13 } 14 if(p[1]){ 15 int i, j; 16 for(i = 2;p[i] == p[1] + i - 1;i ++); 17 if(p[i - 1] == n){ 18 for(j = i;j <= n && p[j] <= j - i;j ++); 19 if(j > n){ 20 printf("%d ", n - i + 1); 21 return 0; 22 } 23 } 24 } 25 for(Rint i = 1;i <= n;i ++) ans = max(ans, p[i] - i + n + 1); 26 printf("%d", ans); 27 }
D. Nauuo and Circle
我们发现,对于节点$x$的子树,它在排列中必定是一段连续的区间,否则就会跟其他的子树导致边相交。
这个排列是可以旋转的,所以钦定$p_1=1$。
设节点$i$的度数为$deg_i$。
我们使用捆绑法,将必须要连在一起的先捆绑起来,之后再对子树进行递归。
例如样例1,2就是这样的:
$$(1,(2,4),3)$$
$$(1,2,3,4)$$
(同个括号里的表示必须要连续)
对于节点$1$,我们可以任意排列它的$deg_1$棵子树,对于其他节点$x$,我们可以排列它自己和$deg_x-1$棵子树
$$Ans=nprod_{i=1}^ndeg_i!$$

1 #include<bits/stdc++.h> 2 #define Rint register int 3 using namespace std; 4 typedef long long LL; 5 const int N = 200003, mod = 998244353; 6 int n, fac[N], deg[N], ans; 7 int main(){ 8 scanf("%d", &n); 9 for(Rint i = 1;i < n;i ++){ 10 int a, b; 11 scanf("%d%d", &a, &b); 12 deg[a] ++; deg[b] ++; 13 } 14 fac[0] = ans = 1; 15 for(Rint i = 1;i <= n;i ++) fac[i] = (LL) i * fac[i - 1] % mod; 16 for(Rint i = 1;i <= n;i ++) ans = (LL) ans * fac[deg[i]] % mod; 17 printf("%d ", (LL) ans * n % mod); 18 }