codeforces1311E
sol:先建一条链,然后把下面的点一个个往上面移, 优先移到最上面,如果上面满了就往下一层, 知道刚刚好凑满距离,如果最后不能移了就说明不能凑出给定的距离
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pii; #define fi first #define se second #define fz1(i,n) for ((i)=1;(i)<=(n);(i)++) #define fd1(i,n) for ((i)=(n);(i)>=1;(i)--) #define fz0g(i,n) for ((i)=0;(i)<=(n);(i)++) #define fd0g(i,n) for ((i)=(n);(i)>=0;(i)--) #define fz0k(i,n) for ((i)=0;(i)<(n);(i)++) #define fd0k(i,n) for ((i)=(((long long)(n))-1);(i)>=0;(i)--) #define fz(i,x,y) for ((i)=(x);(i)<=(y);(i)++) #define fd(i,y,x) for ((i)=(y);(i)>=(x);(i)--) #define ff(c,itr) for (__typeof((c).begin()) itr=(c).begin();itr!=(c).end();++itr) #define pb push_back #define mp make_pair #define inf LLONG_MAX #define iinf INT_MAX const char al='\n'; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); #ifndef ONLINE_JUDGE freopen("test.in","r",stdin); #endif int T; cin>>T; while(T--) { int n,m,i,j; cin>>n>>m; vector<int>a(n+5); int jyl=0,wn=1,wq=n; fz1(i,n) { a[i]=1; jyl+=i-1; } while(jyl>m&&wq>wn+1) { int oo=jyl-m; if(wq-wn-1<=oo) { jyl-=wq-wn-1; a[wn+1]++; a[wq]--; wq--; if(a[wn+1]==(1<<wn)) wn++; } else { int x=wq-oo; if(a[x]<(1<<(x-1))) { jyl-=oo; a[x]++; a[wq]--; wq--; }else break; } } if(jyl==m) { cout<<"YES"<<al; vector<int>fa,now; fa.pb(1); int index=1; fz(i,2,wq) { now.clear(); fz1(j,a[i]) { now.pb(++index); cout<<fa[j%fa.size()]<<" "; }fa=now; }cout<<al; } else cout<<"NO"<<al; } return 0; }
河田は河田、赤木は赤木……。
私は誰ですか。教えてください、私は誰ですか。
そうだ、俺はあきらめない男、三井寿だ!