题意:给你n和k (k|n) 有n个数 第i个数权值为i 要你求权值相同且分成k组 且每组的个数为n/k
思路:恶心构造题,首先对于总权值不能分为k份的 显然不能分成 然后 我们把n/k 分奇偶 我们可以发现 偶数我们可以每k个当成一组
对于奇数 我们可以先处理前3*k 然后同样处理剩下的数
#include <bits/stdc++.h> #define ls(x) T[x].ch[0] #define rs(x) T[x].ch[1] #define fa(x) T[x].fa #define root T[0].ch[1] using namespace std; const int N = 1e5+7; const int inf = 0x3f3f3f3f; typedef long long ll; const ll mod = 1e9+7; int vis[N]; vector<ll> v[N]; ll te[N]; int main(){ //ios::sync_with_stdio(false); //cin.tie(0); cout.tie(0); int t; scanf("%d",&t); while(t--){ ll n,k; scanf("%lld%lld",&n,&k); for(int i=0;i<k;i++) v[i].clear(); memset(te,0,sizeof(te)); ll x=(n*(n+1))/2; bool f=1; if(n==1&&k==1){ printf("yes\n"); printf("1\n"); continue; } if(x%k!=0) f=0; if(f&&n>(x/k)) f=0; if(f){ if((n/k)%2==0){ for(ll i=1;i<=n/2;i++){ v[i%k].push_back(i); v[i%k].push_back(n-i+1); } printf("yes\n"); for(int i=0;i<=k-1;i++){ for(int j=0;j<v[i].size();j++) if(j==0) printf("%lld",v[i][j]); else printf(" %lld",v[i][j]); printf("\n"); } }else{ if(k&1){ for(ll i=1;i<=k;i++){ v[i%k].push_back(i); te[i%k]+=i; } for(ll i=1;i<=k;i++){ v[(i-k/2+k)%k].push_back(i+k); te[(i-k/2+k)%k]+=(i+k); } for(ll i=1;i<=k;i++){ v[i%k].push_back((1+3*k)*3/2-te[i%k]); } for(ll i=1;i<=(n-3*k)/2;i++){ v[i%k].push_back(i+3*k); v[i%k].push_back(n-i+1); } printf("yes\n"); for(int i=0;i<=k-1;i++){ for(int j=0;j<v[i].size();j++) if(j==0) printf("%lld",v[i][j]); else printf(" %lld",v[i][j]); printf("\n"); } }else{ printf("no\n"); } } }else{ printf("no\n"); } } return 0; }