A 
记录每个数出现的次数\(a\) ,如果存在\(a\) 为奇数,那么输出YES。否则最后输出NO。
#include  <bits/stdc++.h>  #define  lowbit(x) x&(-x) const  int  MAXN=2e5 +10 ;const  int  mod=998244353 ;using  namespace  std;using  ll=long  long ;void  solve ()  ;int  main ()  {	int  t=1 ;	 	cin>>t; 	while (t--)	 	{ 		solve (); 	} } int  mp[MAXN];void  solve ()  {		int  n;	cin>>n; 	memset (mp,0 ,sizeof (mp)); 	vector<int > a (n+1 ,0 )  ; 	for (int  i=1 ;i<=n;i++) 	{ 		cin>>a[i]; 		mp[a[i]]++; 	} 	for (int  i=1 ;i<=n;i++) 	{ 		if (mp[a[i]]%2 ) 		{ 			cout<<"YES\n" ; 			return ; 		} 	} 	cout<<"NO\n" ; } 
 
B 
不难想到在\(x\) 的右边所有数的总和小于0,而在\(y\) 的左边所有数的总和小于0,所以先初始化为1,然后在\(x+1,x+3······\) 这样交替进行构造。\(y-1,y-3\) 也是如此。
#include  <bits/stdc++.h>  #define  lowbit(x) x&(-x) const  int  MAXN=2e5 +10 ;const  int  mod=998244353 ;using  namespace  std;using  ll=long  long ;void  solve ()  ;int  main ()  {	int  t=1 ;	 	cin>>t; 	while (t--)	 	{ 		solve (); 	} } int  a[MAXN];void  solve ()  {		int  n,x,y;	cin>>n>>x>>y; 	for (int  i=1 ;i<=n;i++) 	{ 		a[i]=1 ; 	} 	for (int  i=x+1 ;i<=n;i+=2 ) 	{ 		a[i]=-1 ; 	} 	for (int  j=y-1 ;j>=1 ;j-=2 ) 	{ 		a[j]=-1 ; 	} 	for (int  i=1 ;i<=n;i++) 	{ 		cout<<a[i]<<" " ; 	} 	cout<<"\n" ; } 
 
C 
对原序列求一次MAD操作得到数组\(b\) ,不难发现:\(b\) 数组是一个单调递增的数组,每次操作后是对\(b\) 进行向右平移操作,前面用0补充。需要注意的是:
如果同一个数字在\(b\) 中出现多次,那么做一次MAD运算后是右移。
如果是出现一次的话,就用前面的进行填充即可,再计算上贡献。
#include  <bits/stdc++.h>  #define  lowbit(x) x&(-x) const  int  MAXN=2e5 +10 ;const  int  mod=998244353 ;using  namespace  std;using  ll=long  long ;void  solve ()  ;int  main ()  {	int  t=1 ;	 	cin>>t; 	while (t--)	 	{ 		solve (); 	} } ll a[MAXN]; ll b[MAXN]; ll mp[MAXN]; map<ll,int > m; void  solve ()  {		int  n;	cin>>n; 	ll maxn=0 ; 	m.clear (); 	for (int  i=1 ;i<=n;i++) 	{ 		mp[i]=b[i]=0 ; 	} 	ll sum=0 ; 	ll tmp=0 ; 	for (int  i=1 ;i<=n;i++) 	{ 		cin>>a[i]; 		sum+=a[i]; 		if (mp[a[i]]) 		{ 			b[i]=max (a[i],maxn); 			maxn=max (b[i],maxn); 		} 		else  		{ 			mp[a[i]]++; 			b[i]=b[i-1 ]; 		} 	} 	for (int  i=1 ;i<=n;i++) 	{ 		m[b[i]]++; 	} 	for (int  i=1 ;i<=n;i++) 	{ 		if (m[b[i]]>=2 ) 		{ 			sum+=b[i]*(n-i+1 ); 		} 		else 	 		{ 			sum+=b[i]+b[i-1 ]*(n-i); 			b[i]=b[i-1 ]; 		} 	} 	cout<<sum<<"\n" ; } 
 
另外的方法:实际上模拟两次即可(模拟完两次后,出现一次的元素就消失了,直接计算出现多次的情况即可)。
#include  <bits/stdc++.h>  using  u32 = unsigned ;using  i64 = long  long ;using  u64 = unsigned  long  long ;void  solve ()   {    int  n;     std::cin >> n;          std::vector<int > a (n)  ;     for  (int  i = 0 ; i < n; i++) {         std::cin >> a[i];     }          i64 ans = 0 ;          for  (int  t = 0 ; t < 2 ; t++) {         std::vector<int > vis (n + 1 )  ;         int  mx = 0 ;         for  (auto  &x : a) {             ans += x;             if  (vis[x]) {                 mx = std::max (mx, x);             }             vis[x] = 1 ;             x = mx;         }     }     for  (int  i = 0 ; i < n; i++) {         ans += 1LL  * (n - i) * a[i];     }     std::cout << ans << "\n" ; } int  main ()   {    std::ios::sync_with_stdio (false );     std::cin.tie (nullptr );          int  t;     std::cin >> t;          while  (t--) {         solve ();     }          return  0 ; } 
 
D 
后来补的题目:应该是按照题目进行模拟吧。
关键是样例二,可以用方块进行跨行填补。代码细节比较多,不太好调。
最后需要留意的是用\(a[n]\) 特判一下。
#include  <bits/stdc++.h>  #define  lowbit(x) x&(-x) const  int  MAXN=2e5 +10 ;const  int  mod=998244353 ;using  namespace  std;using  ll=long  long ;void  solve ()  ;int  main ()  {	int  t=1 ;	 	cin>>t; 	while (t--)	 	{ 		solve (); 	} } int  a[MAXN];void  solve ()  {		int  n;	cin>>n; 	for (int  i=1 ;i<=n;i++) 	{ 		cin>>a[i]; 	} 	int  ans=0 ; 	for (int  i=1 ;i<n;i++) 	{ 		if (a[i]==0 )	continue ; 		else  if (a[i]>2 ) 		{ 			ans++; 		} 		else  		{ 			if (a[i+1 ]<=2 ) 			{ 				ans++; 				a[i+1 ]=0 ; 			}              			else  if (a[i+1 ]<=4  && a[i+2 ]>2  && i+2 <=n) 			{ 				ans+=2 ; 				a[i+1 ]=0 ; 				a[i+2 ]-=2 ; 			} 			else  			{ 				ans++; 			} 		} 	} 	if (a[n])	ans++; 	cout<<ans<<"\n" ; }