Good Bye 2022: 2023 is NEAR 题解

Koxia and Whiteboards

Statement
Kiyora 有 n n n块白板,从 1 1 1 n n n 编号。初始情况下, 第 i i i 块白板上写着一个整数 a i a_i ai
Koxia 要进行 m m m次操作。第 j j j 次操作是,选择一块白板并将上面的整数修改为 b j b_j bj
计算全部操作后所有白板上数字之和的最大可能值。

每次操作修改最小的数。

#include<bits/stdc++.h> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
						For(j,m-1) cout<<a[i][j]<<' ';\
						cout<<a[i][m]<<endl; \
						} 
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
	return x*f;
} 
ll a[101010];
int main()
{
//	freopen("A.in","r",stdin);
//	freopen(".out","w",stdout);
	int T=read();
	while(T--){
		int n=read(),m=read();
		if(n==1) {
			For(i,n+m) cin>>a[i];
			cout<<a[n+m]<<endl;
			continue;
		}
		priority_queue<ll, vector<ll>, greater<ll> > q;
		For(i,n) {
			q.push(read());
		}
		For(i,m) q.pop(),q.push(read());
		ll ans=0;
		while(!q.empty()) ans+=q.top(),q.pop();
		cout<<ans<<endl;
		
	}
	
	return 0;
}

Koxia and Permutation

Statement
Reve 有两个整数 n n n k k k
对于一个长度为 n n n的排列 p p p,我们令 c c c 是一个长度为 n − k + 1 n-k+1 nk+1的数组,其中

c i = m a x ( p i , ⋯   , p i + k − 1 ) + m i n ( p i , ⋯   , p i + k − 1 ) c_i = max(p_i,\cdots, p_{i+k-1})+min(p_i,\cdots, p_{i+k-1}) ci=max(pi,,pi+k1)+min(pi,,pi+k1)
定义一个排列 p p p 的代价是 c c c 中的最大值。
Koxia 希望你构造一个排列使得其代价尽可能小。

Statement
Joi 有一个数组 a a a,包含 n n n 个正整数。Koxia 希望你判定是否存在一个正整数 x x x 使得 g c d ( a i + x , a j + x ) = 1 gcd(a_i+x,a_j+x)=1 gcd(ai+x,aj+x)=1
对于所有 1 ≤ i < j ≤ n 1\le i \lt j \le n 1i<jn 都成立。

#include<bits/stdc++.h> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
						For(j,m-1) cout<<a[i][j]<<' ';\
						cout<<a[i][m]<<endl; \
						} 
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
	return x*f;
} 
ll a[101010];
int main()
{
//	freopen("A.in","r",stdin);
//	freopen(".out","w",stdout);
	int T=read();
	while(T--){
		int n=read(),m=read();
		int b=n,a=1;
		For(i,n) if(i%m==0) {
			cout<<a++<<' ';
		} else cout<<b--<<' ';
		cout<<endl;
	}
	
	return 0;
}

Koxia and Number Theory

#include<bits/stdc++.h>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int>
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
						For(j,m-1) cout<<a[i][j]<<' ';\
						cout<<a[i][m]<<endl; \
						}
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
	return x*f;
}

set<int> aa[101];
set<int> bb[101];

ll a[101];

bool work() {
	int n=read();
	For(i,n) cin>>a[i];
	sort(a+1,a+1+n);
	bool fl=1;
	For(i,n-1) if(a[i]==a[i+1]) {
		return 0;
	}
	For(i,n) aa[i].clear(),bb[i].clear();
	For(i,n) {
	    Fork(j,2,n) {
            int t=a[i]%j;
            if (aa[j].find(t)!=aa[j].end()) {
                bb[j].insert(t);
            } else {
                aa[j].insert(t);
            }
	    }
	}

    Fork(j,2,n) if (bb[j].size()==j) return 0;
    return 1;
}
int main()
{
	int T=read();
	while(T--){
		bool fl=work();
		puts(fl?"YES":"NO");
	}
	return 0;
}

Koxia and Game

Koxia 和 Mahiru 正在用三个长度为 n n n的数组 a , b , c a,b,c a,b,c 玩一个游戏。其中 a , b , c a,b,c a,b,c中的每个元素都是 1 1 1 n n n 之间的整数。
游戏持续 n n n 轮。在第 i i i 轮中,她们进行以下操作:
S S S { a i , b i , c i } \{ a_i,b_i,c_i \} {ai,bi,ci} 的可重集。
Koxia 从可重集 S S S中选择一个元素并移除。
Mahiru 从可重集 S S S 的剩余两个元素中选择一个元素。
d i d_i di是第 i i i 轮中 Mahiru 选择的元素。如果 d d d 是一个排列 ,则 Koxia 获胜;否则 Mahiru 获胜。
现在,只有 a a a b b b 两个数组是已经确定的。作为 Koxia 的支持者,你希望选择合适的数组 c c c 使得 Koxia 获胜。计算这样的 c c c 的数量,输出其对998244353 取模后的结果。
Koxia 和 Mahiru 会以最优方式行动。

c c c满足条件当且仅当
∀ i ∈ [ 1 , n ] ⋂ Z , ∃ p ∈ [ 1 , n ] ⋂ Z , ( a p = = i ) + ( b p = = i ) + ( c p = = i ) > 1 \forall i \in [1,n]\bigcap Z, \exists p\in [1,n]\bigcap Z,(a_p==i)+(b_p==i)+(c_p==i)>1 i[1,n]Z,p[1,n]Z,(ap==i)+(bp==i)+(cp==i)>1
所以对于每个数 x x x a i , b i a_i,b_i ai,bi出现次数为0次时,无解
1次时,对应位置的 c i = x c_i=x ci=x
出现3次或以上,那么至少有一个数出现至多1次,找出它能至少再填一个数。最后考虑每个数出现2次的情况,那么由于每个数出现两次,我们将a,b对应的相同数连线,分两种情况 :
a i = b i a_i=b_i ai=bi情况下 c i c_i ci填任意数
a i ! = b i a_i!=b_i ai!=bi此时环长度大于2, c i c_i ci只有2种填法( a i a_i ai or b i b_i bi)且环中其他位置的 c i c_i ci也确定了。
答案 = 2 长度大于 2 的环的个数 ∗ n 长度等于 2 的环的个数 =2^{长度大于2的环的个数}*n^{长度等于2的环的个数} =2长度大于2的环的个数n长度等于2的环的个数

#include<bits/stdc++.h> 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i<n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (998244353)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector<int> 
#define pi pair<int,int>
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<<a[i]<<' '; cout<<a[n]<<endl;
#define PRi2D(a,n,m) For(i,n) { \
						For(j,m-1) cout<<a[i][j]<<' ';\
						cout<<a[i][m]<<endl; \
						} 
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
	return x*f;
} 
ll a[3][112345];
int deg[112345];
set<pair<int,int> > h[112345];
int n;
ll ans[112345];
ll work() {
	n=read();
	For(i,n) ans[i]=deg[i]=0;
	For(j,2)For(i,n){
		int t=read();
		a[j][i]=t;
		deg[t]++;
		h[t].insert(mp(j,i));
	}
	queue<int> q;
	For(i,n) {
		if(!deg[i]) return 0;
		if(deg[i]==1) {
			q.push(i);
		}
	}
	while(!q.empty()) {
		int p=q.front();q.pop();
		deg[p]--;
		auto it = h[p].begin();
		auto pa=*it;
		h[p].erase(it);
		ans[pa.se]=p;
		int afi=3-pa.fi;
		int p2=a[afi][pa.se];
		deg[p2]--;
		h[p2].erase(mp(afi,pa.se));
		if(deg[p2]==0) return 0;
		else if(deg[p2]==1) q.push(p2);
	}
	ll aa=1;
	For(i,n) if(deg[i]==2) {
		int p=i,c=0;
		while(deg[p]>0) {
			deg[p]--;
			auto it = h[p].begin();
			auto pa=*it;
			h[p].erase(it);
			int afi=3-pa.fi;
			int p2=a[afi][pa.se];
			deg[p2]--;
			h[p2].erase(mp(afi,pa.se));
			p=p2;
			c+=2;
		}
		if(c==2) aa=mul(aa,n);
		else aa=mul(aa,2);
	}
	return aa;	
}
int main()
{
//	freopen("D.in","r",stdin);
//	freopen(".out","w",stdout);
	int T=read();
	while(T--){
		ll an=work();
		cout<<an<<endl;
		For(i,n) h[i].clear();	
	}
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值