ZOJ Bizarre Routine 分析上下界(2013 ACM/ICPC Asia Regional Changsha Online B)
We've got a bizarre routine here:
bool less_than(x, y) { T++; return x < y; } void work(array[], l, r) { if (l >= r) return; swap(array[(l * A + r * B) / (A + B)], array[r]); int index = l; for (i = l; i < r; i++) if (less_than(array[i], array[r])) swap(array[index++], array[i]); swap(array[r], array[index]); work(array, l, index - 1); work(array, index + 1, r); } void main() { T = 0; Input(n, expect, A, B, array[]); work(array, 0, n - 1); if (T == expect) Output("YES"); else Output("NO"); }
Now the question is: For given n, expect, A and B, how to arrange the input array to make the routine output "YES"?
To simplify the problem, we assume that the input array must be a permutation of 1 to n, and the division in the routine is integer division.
Input
There will be no more than 100 test cases, each case contains 4 integers n (1 ≤ n ≤ 10000), expect (1 ≤ expect ≤ 100000000), A (1 ≤ A ≤ 10) and B (1 ≤ B ≤ 10) in one line.
Output
If there exists an arrangement to make the routine output "YES", please print these corresponding n integers in one line, and seperate them by single spaces. Please be aware that these n integers must be a permutation of 1 to n and the answer might not be unique.
If there isn't any arrangement to make it output "YES", please print "NOWAY" in a line.
Sample Input
6 10 2 1 12 15 1 1
Sample Output
4 5 1 2 3 6 NOWAY
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <vector> 7 #include <cstdio> 8 #include <cstring> 9 #include <algorithm> 10 using namespace std; 11 #define maxn 11015 12 #define mod 1000000007 13 #define INF 0x7fffffff 14 #define ll long long 15 //#define ll __int64 16 int p[maxn]; 17 int mi[maxn]; 18 int n,m,a,b; 19 void back(int l,int m,int r,int id){ 20 p[m]=m;swap(p[m],p[r]);swap(p[r],p[id]); 21 } 22 void work(int l,int r,int c){ 23 if(l>r)return; 24 if(l==r){p[l]=l;return;} 25 int l_l=l,l_r=((l+r)>>1)+1,m; 26 c-=r-l; 27 while(l_l<l_r){ 28 m=(l_l+l_r)>>1; 29 if(mi[m-l]+mi[r-m]>c)l_l=m+1; 30 else l_r=m; 31 } 32 m=l_l; 33 work(l,m-1,mi[m-l]); 34 work(m+1,r,c-mi[m-l]); 35 back(l,m,r,(l*a+r*b)/(a+b)); 36 } 37 int main(){ 38 for(int i=2;i<=maxn;i++){ 39 int x=i/2,y=i-x-1; 40 mi[i]=mi[x]+mi[y]+i-1; 41 } 42 while(~scanf("%d%d%d%d",&n,&m,&a,&b)){ 43 if(m<mi[n]||m>(n-1)*(n)/2){printf("NOWAY\n");continue;} 44 work(0,n-1,m); 45 for(int i=0;i<n;i++)printf(i==n-1?"%d\n":"%d ",p[i]+1); 46 } 47 return 0; 48 }
浙公网安备 33010602011771号