A. Array Divisibility
需要讓滿足$ k\mid j $ 的所有\(a_j\)的和整除k,只需要讓每個\(a_j\)整除k就可以了,可以讓\(a_j=j\)
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
typedef pair<int,int> pii;
typedef unsigned long long ull;
typedef long long ll;
const int N = 2e5+5,M=20,mod=998244353,P=131;
void solve(){
int n;
cin>>n;
for(int i=1;i<=n;i++)cout<<i<<" ";
cout<<endl;
}
void fast(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
}
signed main(){
fast();
int t=1;
cin>>t;
while(t--)solve();
return 0;
}
B. Corner Twist
可以知道,大矩形的操作可以由小矩形合成,兩次副對角+1的操作可以合成為主對角+1的操作
於是使用最小的,副對角為1的矩形操作,從上到下,從左到右,最後判斷相等就可以了
#include<bits/stdc++.h>
using namespace std;
//#define int long long
#define endl '\n'
typedef pair<int,int> pii;
typedef unsigned long long ull;
typedef long long ll;
const int N = 505,M=20,mod=998244353,P=131;
int mp1[N][N];
int mp2[N][N];
void solve(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%1d",&mp1[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%1d",&mp2[i][j]);
for(int i=1;i<n;i++){
for(int j=1;j<m;j++){
while(mp1[i][j]!=mp2[i][j]){
mp1[i][j]=(mp1[i][j]+1)%3;
mp1[i+1][j]=(mp1[i+1][j]+2)%3;
mp1[i+1][j+1]=(mp1[i+1][j+1]+1)%3;
mp1[i][j+1]=(mp1[i][j+1]+2)%3;
}
}
}
int flag=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(mp1[i][j]!=mp2[i][j])flag=0;
}
}
if(flag)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
void fast(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
}
signed main(){
// fast();
int t=1;
cin>>t;
while(t--)solve();
return 0;
}
C. Have Your Cake and Eat It Too
雙指標列舉中間的一段,然後字首和判斷左右兩邊能不能用就行了
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
typedef pair<int,int> pii;
typedef unsigned long long ull;
typedef long long ll;
const int N = 505,M=20,mod=998244353,P=131;
void solve(){
int n;
cin>>n;
vector<int> a(n+2),b(n+2),c(n+2);
vector<int> qza(n+2),qzb(n+2),qzc(n+2);
vector<int> hza(n+2),hzb(n+2),hzc(n+2);
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)cin>>b[i];
for(int i=1;i<=n;i++)cin>>c[i];
int sum=0;
for(int i=1;i<=n;i++)sum+=a[i];
int tp=(sum+2)/3;
for(int i=1;i<=n;i++){
qza[i]=qza[i-1]+a[i];
qzb[i]=qzb[i-1]+b[i];
qzc[i]=qzc[i-1]+c[i];
}
for(int i=n;i>=1;i--){
hza[i]=hza[i+1]+a[i];
hzb[i]=hzb[i+1]+b[i];
hzc[i]=hzc[i+1]+c[i];
}
int l=1,s=0;
for(int r=1;r<=n;r++){
s+=a[r];
while(s-a[l]>=tp)s-=a[l++];
if(qzb[l-1]>=tp&&hzc[r+1]>=tp){
cout<<l<<" "<<r<<" "<<1<<" "<<l-1<<" "<<r+1<<" "<<n<<endl;
return ;
}
if(qzc[l-1]>=tp&&hzb[r+1]>=tp){
cout<<l<<" "<<r<<" "<<r+1<<" "<<n<<" "<<1<<" "<<l-1<<endl;
return ;
}
}
l=1,s=0;
for(int r=1;r<=n;r++){
s+=b[r];
while(s-b[l]>=tp)s-=b[l++];
if(qza[l-1]>=tp&&hzc[r+1]>=tp){
cout<<1<<" "<<l-1<<" "<<l<<" "<<r<<" "<<r+1<<" "<<n<<endl;
return ;
}
if(qzc[l-1]>=tp&&hza[r+1]>=tp){
cout<<r+1<<" "<<n<<" "<<l<<" "<<r<<" "<<1<<" "<<l-1<<endl;
return ;
}
}
l=1,s=0;
for(int r=1;r<=n;r++){
s+=c[r];
while(s-c[l]>=tp)s-=c[l++];
if(qza[l-1]>=tp&&hzb[r+1]>=tp){
cout<<1<<" "<<l-1<<" "<<r+1<<" "<<n<<" "<<l<<" "<<r<<endl;
return ;
}
if(qzb[l-1]>=tp&&hza[r+1]>=tp){
cout<<r+1<<" "<<n<<" "<<1<<" "<<l-1<<" "<<l<<" "<<r<<endl;
return ;
}
}
cout<<-1<<endl;
return ;
}
void fast(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
}
signed main(){
fast();
int t=1;
cin>>t;
while(t--)solve();
return 0;
}
D. Swap Dilemma
可以知道,更大的操作可以由更小的操作合成,所以只需要交換兩個相鄰數就可以了,那麼我們不妨把兩個陣列都交換成升序,如果這樣做,因為其中一個交換時另外一個必須同時交換,並且同一對位置交換兩次就抵消,所以就是看兩者的交換次數是不是同奇偶,交換次數計算逆序對就行了。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
typedef pair<int,int> pii;
typedef unsigned long long ull;
typedef long long ll;
const int N = 1e5+5,M=20,mod=998244353,P=131;
int tmp[N];
int merge_sort(vector<int> &a,int l,int r){
if(l>=r)return 0;
int mid=l+r>>1,res=0;
res+=merge_sort(a,l,mid);
res+=merge_sort(a,mid+1,r);
int i=l,j=mid+1,cnt=l;
while(i<=mid&&j<=r){
if(a[i]<=a[j])tmp[cnt++]=a[i++];
else {
res+=mid-i+1;
tmp[cnt++]=a[j++];
}
}
while(i<=mid)tmp[cnt++]=a[i++];
while(j<=r)tmp[cnt++]=a[j++];
for(i=l;i<=r;i++)a[i]=tmp[i];
return res;
}
void solve(){
int n;
cin>>n;
vector<int> a(n+1),b(n+1);
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)cin>>b[i];
int ra=merge_sort(a,1,n);
int rb=merge_sort(b,1,n);
int flag=1;
for(int i=1;i<=n;i++)
if(a[i]!=b[i])flag=0;
if(abs(ra-rb)%2==0&&flag)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
void fast(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
}
signed main(){
fast();
int t=1;
cin>>t;
while(t--)solve();
return 0;
}
E. I Love Balls
因為挑選到特殊球可以繼續往下挑選,一直到挑選到普通球為止,那麼我們不妨先計算普通球的貢獻,再以插空的方式計算特殊球的貢獻。可以知道每個普通球對先手者的貢獻是\(\frac{\lceil\frac{n-k}{2}\rceil}{n-k}\cdot a[i]\), 每個普通球對後手者的貢獻是\(\frac{\lfloor\frac{n-k}{2}\rfloor}{n-k}\cdot a[i]\),然後再插空計算貢獻,有\(n-k+1\)個空,所以每個特殊球對先手者的貢獻是\(\frac{\lceil\frac{n-k+1}{2}\rceil}{n-k+1}\cdot a[i]\),每個特殊球對後手者的貢獻是\(\frac{\lfloor\frac{n-k+1}{2}\rfloor}{n-k+1}\cdot a[i]\) 。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
typedef pair<int,int> pii;
typedef unsigned long long ull;
typedef long long ll;
const int N = 2e5+5,M=20,mod=1e9+7,P=131;
int qmi(int a,int k){
int res=1;
while(k){
if(k&1)res=res*a%mod;
a=a*a%mod;
k>>=1;
}
return res;
}
void solve(){
int n,k;
cin>>n>>k;
vector<int> a(n+1);
for(int i=1;i<=n;i++)cin>>a[i];
int ans1=0,ans2=0;
for(int i=k+1;i<=n;i++){
ans1=(ans1+(n-k+1)/2*a[i]%mod*qmi(n-k,mod-2)%mod)%mod;
ans2=(ans2+(n-k)/2*a[i]%mod*qmi(n-k,mod-2)%mod)%mod;
}
for(int i=1;i<=k;i++){
ans1=(ans1+(n-k+2)/2*a[i]%mod*qmi(n-k+1,mod-2)%mod)%mod;
ans2=(ans2+(n-k+1)/2*a[i]%mod*qmi(n-k+1,mod-2)%mod)%mod;
}
cout<<ans1<<" "<<ans2<<endl;
}
void fast(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
}
signed main(){
fast();
int t=1;
cin>>t;
while(t--)solve();
return 0;
}