In this blue bridge cup, from the point of view of the topic, the familiar search questions are obviously reduced, the difficulty of using mathematical knowledge and even some questions also use some knowledge of number theory, dynamic planning, large number operation, sorting, dfs, personal feeling that the overall difficulty of the test question is increased. Maybe he was scolded for "violence Cup" and "search Cup".

subject | Using knowledge points / algorithm types |
---|---|

Day after | Water problem |

Square count | Distance formula of mathematical knowledge |

Complex power | Large number operation file output |

Number of tests | dp |

Quick sort | sort |

Incrementing triples | Sort double pointer |

Log statistics | Sorting custom one to many data structures |

global warming | dfs |

Heap count | Fast power and module operation of number theory knowledge |

### The 9th Java group B

# Day after

Title: day January 1, 2000 is the first day of that year. So, May 4th, 2000, is the first day of that year? Note: you need to submit an integer. Do not fill in any extra content.

Open calendar From January to May: 31 29 31 30 4 Answer: 125

# Square count

Title: grid count As shown in figure p1.png, there are countless 1x1 small squares on the two-dimensional plane. We draw a circle with a radius of 1000 with a vertex of a small square as the center. Can you work out how many complete squares there are in this circle? Note: you need to submit an integer. Do not fill in any extra content. /* Because the circle is symmetric, you only need to count the number of squares in the positive half axis and multiply it by 4 to get the total number In fact, the distance between the upper right point of the square and the center of the circle is less than or equal to the radius Answer: 3137548 */

package The ninth; /** * @author JohnnyLin * @version Creation Time: 2020 8:30:11 PM, May 28, 2010 * Class description */ public class t02_Square count { public static void main(String[] args) { int r=1000; int ans=0; for (int i = 1; i <= r; i++) { for (int j = 1; j <= r; j++) { if(i*i+j*j<=r*r) ans++; } } System.out.println(ans*4); } }

# Complex power

Title: complex power Let i be the imaginary unit. For any positive integer n, the real and virtual parts of (2+3i)^n are integers. How much is (2+3i)^123456? That is to say, 123456 power of (2+3i). This number is very large and requires accurate representation. The answer is written in the form of "real part ± virtual part i". The real part and virtual part are integers (cannot be expressed by scientific counting method), no spaces are added in the middle, and no positive sign is added before the real part is the timing. (2+3i)^2 is written as: - 5+12i, (2+3i)^5 written as: 122-597i Note: what needs to be submitted is a very large complex number, do not fill in any redundant content. /* I didn't want to use long to get the wrong answer of 4043220979119144065 - 7374402350132176768i In fact, this problem should use large data storage because 2 ^ 123456 must be longer than long (2 ^ 64) */

package The ninth; import java.io.File; import java.io.FileNotFoundException; import java.io.PrintStream; import java.math.BigInteger; /** * @author JohnnyLin * @version Creation Time: 2020 June 2, 2004 4:58:28 PM */ public class t03_Complex power2 { public static void main(String[] args) throws FileNotFoundException { //BigInteger a=new BigInteger(); BigInteger a=BigInteger.valueOf(2); BigInteger b=BigInteger.valueOf(3); BigInteger c=BigInteger.valueOf(2); BigInteger d=BigInteger.valueOf(3); //Multiply according to complex number: (a+b*i)*(c+d*i)=(a*c-b*d)+(b*c+a*d)i for(int i=1;i<=123455;i++) { //Note that temporary variable storage is used here BigInteger t=a.multiply(c).subtract(b.multiply(d)); BigInteger k=b.multiply(c).add(a.multiply(d)); c=t; d=k; } /* * Do you think the direct output is over here? If you don't directly output to the console, you will find that only: * This is because the data is too long. The console can't put down the page directly * Baidu search uses the following methods to save the output results in ans.txt file */ //System.out.println(c.toString()+d.toString()); PrintStream ps = new PrintStream(new File("ans.txt"));//Default path in project System.setOut(ps);//Output in ans.txt in System.out.println(c.toString()+d.toString()+"i"); // System.setOut(out); / / if it is commented, the following will not be input to the console // // System.out.println(a.toString()+b.toString()+"i"); } }

# Number of tests

/* Title: number of tests The residents of Planet x have a bad temper, but the only unusual behavior when they are angry is to drop their cell phones. Major manufacturers have launched a variety of fall resistant mobile phones. The Quality Supervision Bureau of Planet x stipulates that mobile phones must be tested for falling resistance, And evaluate a fall resistance index, and then allow the market circulation. There are many towering towers on Planet x, which can be used for the fall resistance test. Each floor of the tower is the same height. Slightly different from the earth, their first floor is not the ground, but our second floor. If the mobile phone is dropped from the 7th floor and is not broken, but the 8th floor is broken, then the anti falling index of the mobile phone = 7. In particular, if the mobile phone is broken when it is dropped from the first layer, the fall resistance index = 0. If it is thrown to the nth floor of the highest floor of the tower, the resistance index = n In order to reduce the number of tests, three mobile phones were sampled from each manufacturer. The tower height of a test is 1000 floors. If we always adopt the best strategy, How many times does it take to test the phone's fall resistance index in the worst of luck? Please fill in the maximum number of tests. Note: you need to fill in an integer. Do not fill in any extra content. */ /* *It is noted that the number of tests is related to the number of mobile phones and the falling resistance index of mobile phones *Form to get recurrence relation *f1(i)=i f1(i) indicates that the maximum number of tests is i when the fall resistance index of only one mobile phone is i *This is because there is only one mobile phone, so it can only be tested from the first floor (otherwise it may be broken and there will be no mobile phone) * *Here we need to understand the worst luck and the best strategy *The so-called worst luck is the minimum value of all possible kinds of development in the direction of the most test times when the optimal strategy is developed in the direction of the most test times */

package The ninth; /** * @author JohnnyLin * @version Creation Time: 2020 May 28, 2010 10:15:57 PM */ public class t04_Number of tests2 { static final int N=1000; public static void main(String[] args) { int f1[]=new int [N+1]; int f2[]=new int [N+1]; int f3[]=new int [N+1]; //When a mobile phone for (int i = 1; i <= N; i++) { f1[i]=i; } //Two cell phones //When the falling resistance index of mobile phone is i for (int i = 1; i <=N; i++) { int ans=Integer.MAX_VALUE; /*Enumerate the layers to start the test j. there are two test results for each layer *1,It's broken Remember that the number of dropped cell phones is one less. The number of tests for this cell phone is: 1+f1[j-1] 2, Or the number of tests for the phone is: f2[i-j] Take one max as the maximum number of tests that the mobile phone starts to test in this layer The optimal strategy is the minimum value of all the most tests in layer i, a value of j */ for (int j = 1; j <=i; j++) { int max = 1+Math.max(f1[j-1], f2[i-j]); ans=Math.min(max, ans); } f2[i]=ans; } //Three cell phones for (int i = 1; i <=N; i++) { int ans=Integer.MAX_VALUE; /*Enumerate the layers to start the test j. there are two test results for each layer *1,It's broken Remember that the number of dropped cell phones is one less. The number of tests for this cell phone is: 1+f2[j-1] 2, Or it's better. The test times of the mobile phone are: f3[i-j] Take one max as the maximum number of tests that the mobile phone starts to test in this layer The optimal strategy is the minimum value of all the most tests in layer i, a value of j */ for (int j = 1; j <=i; j++) { int max = 1+Math.max(f2[j-1], f3[i-j]); ans=Math.min(max, ans); } f3[i]=ans; } System.out.println(f3[N]); } }

# Quick sort

Title: quick sort The following code finds the smallest element in array a []. It uses a divide and conquer algorithm similar to fast sorting, and the expected time complexity is O(N). Please read and analyze the source code carefully and fill in the missing part of the dash. import java.util.Random; public class Main{ public static int quickSelect(int a[], int l, int r, int k) { Random rand = new Random(); int p = rand.nextInt(r - l + 1) + l; int x = a[p]; int tmp = a[p]; a[p] = a[r]; a[r] = tmp; int i = l, j = r; while(i < j) { while(i < j && a[i] < x) i++; if(i < j) { a[j] = a[i]; j--; } while(i < j && a[j] > x) j--; if(i < j) { a[i] = a[j]; i++; } } a[i] = x; p = i; if(i - l + 1 == k) return a[i]; if(i - l + 1 < k) return quickSelect( _________________________________ ); / / fill in the blank else return quickSelect(a, l, i - 1, k); } public static void main(String args[]) { int [] a = {1, 4, 2, 8, 5, 7}; System.out.println(quickSelect(a, 0, 5, 4)); } } Note: only submit the missing code in the underlined part, and do not copy any existing code or symbols.

package The ninth; /** * @author JohnnyLin * @version Creation Time: 2020 May 28, 2010 10:26:17 PM */ import java.util.Random; public class t05_Quick sort{ /** 1, 4, 2, 8, 5, 7 quickSelect(a, 0, 5, 4) * @param a Array to sort * @param l Left interval subscript * @param r Right section subscript * @param k * @return */ public static int quickSelect(int a[], int l, int r, int k) { //Get pointer at random Random rand = new Random(); int p = rand.nextInt(r - l + 1) + l;// 3 3 3 5 //System.out.println(p); int x = a[p]; //Exchange a[p] selected element and right interval element a[r] int tmp = a[p]; a[p] = a[r]; a[r] = tmp; int i = l, j = r; while(i < j) { while(i < j && a[i] < x) i++; if(i < j) { a[j] = a[i]; j--; } while(i < j && a[j] > x) j--; if(i < j) { a[i] = a[j]; i++; } } a[i] = x; //mid p = i; if(i - l + 1 == k) return a[i]; //The actual ranking is a, p+1, r, k-(i-l+1) on the right //8 6 //3 5 //l=4 r=8 // 2=k-(r-l)=6-(8-4) //Rank k is in this range. Note that this range is shrinking and finally approaching an element if(i - l + 1 < k) return quickSelect( a, i+1,r, k-(i-l+1)); //Fill in the blanks else return quickSelect(a, l, i - 1, k); } public static void main(String args[]) { // int [] a = {1, 4, 2, 8, 5, 7}; // System.out.println(quickSelect(a, 0, 5, 4)); int [] a = {1, 4, 2, 8, 5, 7, 0};//0 1 2 4 5 7 8 System.out.println(quickSelect(a, 0, 6, 1)); int [] b = {1, 4, 2, 8, 5, 7, 0};//0 1 2 4 5 7 8 System.out.println(quickSelect(b, 0, 6, 3)); int [] c = {1, 4, 2, 8, 5, 7, 0};//0 1 2 4 5 7 8 System.out.println(quickSelect(c, 0, 6, 6)); } }

# Incrementing triples

Title: incrementing triples Given three arrays of integers A = [A1, A2, ... AN], B = [B1, B2, ... BN], C = [C1, C2, ... CN]， Please count how many triples (i, j, k) satisfy: 1. 1 <= i, j, k <= N 2. Ai < Bj < Ck [input format] The first line contains an integer N. The second line contains N integers A1, A2,... An. The third line contains N integers B1, B2,... BN. The fourth line contains N integers C1, C2,... CN. For 30% of data, 1 < = n < = 100 For 60% of data, 1 < = n < = 1000 For 100% data, 1 < = n < = 100000 0 < = AI, Bi, CI < = 100000 [output format] An integer represents the answer [input example] 3 1 1 1 2 2 2 3 3 3 [sample output] 27 Resource conventions: Peak memory consumption (including virtual machine) < 256M CPU consumption < 1000ms Please output strictly according to the requirements, and do not print redundant content like "please input...". All the code is put in the same source file. After debugging, copy and submit the source code. Do not use the package statement. Do not use features of jdk1.7 and above. The name of the Main class must be: Main, otherwise it will be treated as invalid code. 3 1 3 1 3 2 5 4 2 6 3 1 1 3 2 3 5 2 4 6

This problem is to choose a number a, B and C from three arrays

Make a < B < C

Because A, B and C are in descending order, O(n) - based double pointer method is used

1. First, compare B[p] with C[k]

If K < n & & B[p] >

2. Then K does not move B[p] to record N-k, that is, the number of the C array greater than B[p]

The sum of the number of prefixes and array records greater than B[p] in the C array as of B[p] = (P = = 0? 0: s [P-1]) + B[p]

3. Then p moves right

Repeat until p or k > = n.

Comparing A[i] with B[j] is similar

1. First, compare A[i] with B[j]

If J < n & & A[i] >

2. Then, j-fixed ans+=s[N-1]-(j==0?0:s[j-1]) obtains the total number of [j,N-1) intervals C greater than Bd

3. Then p moves right

Repeat until i or j > = n

package The ninth; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.Arrays; import java.util.Scanner; /** * @author JohnnyLin * @version Creation Time: 2020 8:55:23 p.m., May 29, 2010 */ public class t06_Incrementing triples2 { // static void show(int a[]) { // for (int i = 0; i < a.length; i++) { // System.out.print(a[i]+" "); // } // System.out.println(); // } public static void main(String[] args) throws FileNotFoundException { System.setIn(new FileInputStream(new File("src/data/in8.txt") ) ); Scanner reader=new Scanner(System.in); int N=reader.nextInt(); int A[]=new int[N]; int B[]=new int[N]; int C[]=new int[N]; int b[]=new int[N];//Number of records greater than B[i] in C array long s[]=new long[N];//Record prefix sum (cumulative sum) exceeds the integer range and is stored in long for (int j = 0; j < N; j++) { A[j]=reader.nextInt(); } for (int j = 0; j < N; j++) { B[j]=reader.nextInt(); } for (int j = 0; j < N; j++) { C[j]=reader.nextInt(); } Arrays.sort(A); Arrays.sort(B); Arrays.sort(C); int p=0; int k=0; while(p<N) { while(k<N&&C[k]<=B[p]) { k++; } b[p]=N-k; s[p]=(p==0?0:s[p-1])+b[p]; p++; } long ans=0; int i=0; int j=0; while(i<N) { while(j<N&&B[j]<=A[i]) { j++; } ans+=s[N-1]-(j==0?0:s[j-1]); i++; } System.out.println(ans); } }

/* This is a mathematical problem that can only be solved by finding the law Divide the spiral broken line into two areas as shown in the figure with y=-x In the upper right corner, the length of each section is 48 12 The sequence of equal difference with tolerance d=4 for the first term a1=4 To calculate the dis of each given point, you can use the lower right corner as the reference point It can be obtained by displacement operation of step step The length of the lower right corner is s(n)=(a(1)+a(n))*n/2=a(1)+(n*(n-1)d)/2 */ package The ninth; import java.util.Scanner; /** * @author JohnnyLin * @version Creation Time: 2020 1:41:18 p.m., June 4, 2010 */ public class t07_Helix2 { public static void main(String[] args) { Scanner reader=new Scanner (System.in); //0 1 int X=reader.nextInt(); int Y=reader.nextInt(); long dis=1; long n=0,ans=0; //Area I if(Y>0&&Math.abs(X)<=Y) { //Item n=Y; //Difference from the reference point in the lower right corner dis=Y-X+2*Y; }else if(X>0&&Math.abs(Y)<=X) { //Area II n=X; dis=Y+X; }else if(Y<=0&&X>=Y-1&&X<=-Y) {//Area 3 n=-Y; dis=-(-Y-X); }else if(X<0&&Y>=X+1&&Y<=-X) { //Area IV n=-X-1; dis=-(Y-X-1-2*X-1); } System.out.println(sum(1L,2*n,1)*2-dis); } static long sum(long a,long n,int d) { return (a+a+(n-1)*d)*n/2; } }

# Log statistics

Title: log statistics Xiaoming maintains a programmer forum. Now he has collected a "like" log with N lines. The format of each line is: ts id Indicates that the post with id number at ts time received a "like". Now Xiaoming wants to count which posts were "hot posts". If a post has received at least K compliments in any time period with a length of D, Xiao Ming thinks that the post was a "hot post". Specifically, if there is a time when t satisfies that the post receives no less than K compliments in the [T, t + D] period (note that it is left closed and right open), the post has been a "hot post". [1,12) Given the log, please help Xiaoming count all the post numbers that used to be "hot posts". [input format] The first line contains three integers, N, D, and K. The following N lines contain two integers ts and id. For 50% of data, 1 < = k < = n < = 1000 For 100% data, 1 < = k < = n < = 100000 0 < = TS < = 100000 0 < = ID < = 100000 [output format] Output the hot post id in the order from small to large. One line per id. [input example] 7 10 2 0 1 0 10 10 10 10 1 9 1 100 3 100 3 [sample output] 1 3 Resource conventions: Peak memory consumption (including virtual machine) < 256M CPU consumption < 1000ms Please output strictly according to the requirements, and do not print redundant content like "please input...". All the code is put in the same source file. After debugging, copy and submit the source code. Do not use the package statement. Do not use features of jdk1.7 and above. The name of the Main class must be: Main, otherwise it will be treated as invalid code. /* First, save the posts with the same id and the time they received their likes One to many structure is used id ts 1 0 9 10 3 100 100 10 0 10 Then enumerate whether the number of likes in [T, t + D] time exceeds K at every possible time point t Note: 1. The hot post id is required to be output from small to large */

package The ninth; import java.util.Arrays; import java.util.Scanner; /** * @author JohnnyLin * @version Creation Time: 2020 2:48:40 PM, May 30, 2010 * Class description */ public class t08_Log statistics2 { //The record class stores the corresponding time and id of each record //Record implements the comparable interface to sort each record public static class record implements Comparable<record>{ int id,ts; record(int id,int ts){ this.id=id; this.ts=ts; } //Rewrite compareTo method, first compare the same id by id, then by ts @Override public int compareTo(record o) { if(this.id==o.id) return this.ts-o.ts; else return this.id-o.id; } } public static void main(String[] args) { Scanner reader=new Scanner(System.in); int N=reader.nextInt(); int D=reader.nextInt(); int K=reader.nextInt(); //Declare an array of likes record blog[]=new record[N]; boolean flag[]=new boolean[100000]; for(int i=0;i<N;i++) { int ts=reader.nextInt(); int id=reader.nextInt(); //Each blog[i] stores a record blog[i]=new record(id,ts); } Arrays.sort(blog); /* * After sorting 1 0 1 9 1 10 3 100 3 100 10 0 10 10 */ // for(int i=0;i<N;i++) { // System.out.println(blog[i].id+" "+blog[i].ts); // // } for(int i=0;i+K-1<N;i++) { int id = blog[i].id; int next=i+K-1; //Minimum requirement (at least): the distance K-1 is still the same id and the time interval is within D if(!flag[id]&&blog[ next].id==id&& (blog[next].ts-blog[i].ts)<D) { flag[id]=true; System.out.println(id); } } } }

# global warming

Title: global warming You have a picture of NxN pixels in a certain sea area, where "." represents ocean and "ා" represents land, as shown below: ....... .##.... .##.... ....##. ..####. ...###. ....... Among them, an island is composed of a piece of land connected in four directions of "up, down, left and right". For example, there are two islands in the picture above. As global warming causes sea levels to rise, scientists predict that in the next few decades, a pixel of the island's edge will be flooded by water. Specifically, if a land pixel is adjacent to the ocean (there are oceans in the four adjacent pixels), it will be submerged. For example, the sea area in the figure above will become the following in the future: ....... ....... ....... ....... ....#.. ....... ....... Please calculate: according to scientists' prediction, how many islands in the picture will be completely submerged. [input format] The first line contains an integer n. (1 <= N <= 1000) The following n rows and N columns represent a picture of the sea area. The photo guarantees that the pixels in the first row, the first column, the nth row and the nth column are all oceans. [output format] An integer represents the answer. [input example] 7 ....... .##.... .##.... ....##. ..####. ...###. ....... [sample output] 1 Resource conventions: Peak memory consumption (including virtual machine) < 256M CPU consumption < 1000ms Please output strictly according to the requirements, and do not print redundant content like "please input...". All the code is put in the same source file. After debugging, copy and submit the source code. Do not use the package statement. Do not use features of jdk1.7 and above. The name of the Main class must be: Main, otherwise it will be treated as invalid code. */ /* Or the previous idea: first, dfs calculates the number of all islands, records them with res, and then counts the number of islands that will not be submerged ans The difference between the two is the number of submerged Islands What's different is that there's a change in the way judgment doesn't get drowned Specifically: In the search process of an island, use the global flag as a sign of whether the island will be submerged or not If there is an island whose adjacent pixels are all land, the island will not be submerged But continue to traverse all the land of the island to mark the corresponding position of the Boolean array vis as true So as to avoid misjudgment The flag here should be set as a global variable or it will never be modified Detection uses local value false boolean flag=false; dfs(i,j,map,flag); if(flag) { ans++; } However, it can't pass the last set of all data. When the data volume is 1000 * 1000, the stack overflows This is because the maximum number of layers allowed by recursion is 10000, which obviously exceeds Therefore, it is impossible to get all the scores by recursive search It seems that none of them can get better solutions through all the data. Welcome to comment area */

package The ninth; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.Scanner; /** * @author JohnnyLin * @version Creation Time: 2020 5:32:40 PM, May 30, 2010 */ public class t09_global warming_optimization { static int N; static char map[][]; static char mapbefore[][]; static boolean flag=false; static boolean vis[][]; //Upper left lower right static int dir[][]={{-1,0},{0,-1},{1,0},{0,1}}; //Determine the number of connected blocks static void dfs(int x,int y,char[][] a) { //dfs exit when all land is marked if(check(x,y)) {//If a piece of land is found surrounded by land, set the flag f to true //But you can't return directly. To traverse the island, mark the corresponding position of vis as true flag=true; } for(int i=0;i<4;i++) { int nx=x+dir[i][0]; int ny=y+dir[i][1]; if(!vis[nx][ny]&&nx>=0&&nx<N&&ny>=0&&ny<N&&a[nx][ny]=='#') { //Note that you don't need to go back and mark false vis[nx][ny]=true; dfs(nx,ny,a); } } } //Determine the number of connected blocks static void dfs_islandNum(int x,int y,char[][] a) { //When all pixels are '.' at the outlet of dfs for(int i=0;i<4;i++) { int nx=x+dir[i][0]; int ny=y+dir[i][1]; if(nx>=0&&nx<N&&ny>=0&&ny<N&&a[nx][ny]=='#') { a[nx][ny]='.'; dfs_islandNum(nx,ny,a); } } } //Judge whether adjacent pixels of a certain land are all land private static boolean check(int x, int y) { for(int i=0;i<4;i++) { int nx=x+dir[i][0]; int ny=y+dir[i][1]; if(nx>=0&&nx<N&&ny>=0&&ny<N) { if(map[nx][ny]=='.') {//Adjacent pixels are the ocean will be submerged return false; } } } return true; } static void show(char [][]a) { for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { System.out.print(a[i][j]); } System.out.println(); } } static void show2(boolean [][]a) { for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { System.out.print(String.format("%5s ", a[i][j])); } System.out.println(); } } public static void main(String[] args) throws FileNotFoundException { //Test sample System.setIn(new FileInputStream(new File("src/data/in7.txt") ) ); Scanner reader=new Scanner(System.in); N=reader.nextInt(); //mapbefore=new char[N][N]; map=new char[N][N]; vis=new boolean[N][N]; mapbefore=new char[N][N]; for (int i = 0; i < N; i++) { String s=reader.next(); for (int j = 0; j < N; j++) { map[i][j]=s.charAt(j); mapbefore[i][j]=map[i][j]; } } int res=0; //Count the number of connected blocks in the previous sea area, i.e. all islands for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if(mapbefore[i][j]=='#') { dfs_islandNum(i,j,mapbefore); res++; } } } //System.out.println(res); int ans=0; //Count the number of connecting blocks in the future sea area, i.e. the islands not submerged for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { if(map[i][j]=='#'&&!vis[i][j]) { dfs(i,j,map); if(flag) { ans++; } //Marking the tag back to false is critical flag=false; } } } //show2(vis); //System.out.println(ans); System.out.println(res-ans); } }

# Heap count

Title: count of heaps We know that a heap with N elements can be regarded as a complete binary tree with N nodes. Each node has a weight. For a small root heap, the weight of the parent node must be less than that of its child nodes. Suppose the weights of N nodes are 1~N, can you find out how many different kinds of small root stacks there are? For example, there are three types of N=4: 1 / \ 2 3 / 4 1 / \ 3 2 / 4 1 / \ 2 4 / 3 Since the number may exceed the integer range, you only need to divide the output by the remainder of 100000009. [input format] An integer N. For 40% of data, 1 < = n < = 1000 For 70% of data, 1 < = n < = 10000 For 100% data, 1 < = n < = 100000 [output format] An integer represents the answer. [input example] 4 [sample output] 3 Resource conventions: Peak memory consumption (including virtual machine) < 256M CPU consumption < 1000ms Please output strictly according to the requirements, and do not print redundant content like "please input...". All the code is put in the same source file. After debugging, copy and submit the source code. Do not use the package statement. Do not use features of jdk1.7 and above. The name of the Main class must be: Main, otherwise it will be treated as invalid code. /* *Using recursive algorithm of small root heap property to solve In the range of 1-N, the root of small root heap is the minimum value of 1-N Root selection hypothesis for left subtree: 1 species; root selection hypothesis for right subtree: r species Take 1 as root, derive left and right subtrees, and then select the unselected ones among the remaining N-1 numbers And the number larger than the root is the root of the new subtree, which is a recursive process of building a small root heap In essence, the process of selecting roots for left and right subtrees is equivalent to the process of dividing sets for left subtrees Assuming that lsize nodes are selected for the left subtree, the number of right nodes is also determined The total number of root selection schemes is: the combination number of N-1 lisze is C(N-1,lisze) Then the total number of heaps is: d(1)=C(N-1,lsize)*d(l)*d(r) Where d(i) represents the number of heap schemes with node i as root 1. Determine N-1 and l, r Recurrence formula of objective formula: d(x)=C(size(x)-1,size(2*x))*d(2*x)*d(2*x+1) Where size(i) indicates the total number of nodes in the tree whose root node is node i For example, when N=5 d(1)=C(4,3)*d(2)*d(3) d(2)=C(2,1)*d(4)*d(5) The number of schemes for the heap of leaf nodes is 1 d(3)=C(1,1)=1 d(4)=d(5)=1 So the total number of schemes: d(1)=4*2=8 2. Find combination number C(N,lsize) c(N,lsize)=N!/(N-lsize)!/ lsize! Preprocessing factorials In the process of factoring, we have redundant the above formula For the combination number, we still need to find the remainder The division of remainder should be transformed into the inverse element of module according to Fermat's small theorem, which will not be expanded here for instance Division of a / B% mod module without allocation law not equal to a%mod /b%mod But it's equal to a*(b about the inverse of the module) The inverse element of b is a^(mod-2) Fast power is used in the process of seeking power So C (n, lSize) = n! * quicikpow ((n-lsize)!, mod-2) * quickpow (lSize!, mod-2) */

package The ninth; import java.util.Scanner; /** * @author JohnnyLin * @version Creation Time: 2020 9:54:08 PM, June 1, 2008 */ public class t10_Heap count2 { static final int mod= 1000000009; static int N; static int[]size;//Record the size[i] of each node to indicate the total number of points in the tree whose root node is node I static long[] a;//The factorial a[i] of record 1~N represents I! static long[] inv;//Record the inverse element of 1~N factorial inv[i] represents the inverse element of I public static void main(String[] args) { Scanner reader = new Scanner(System.in); N = reader.nextInt(); size=new int[N+1]; a=new long[N+1]; inv=new long[N+1]; initSize(); initA(); System.out.println(dp()); } private static void initSize() { // for(int i=N;i>=1;i--) { // if(2*i+1<=N) { // size[i]=size[2*i]+size[2*i+1]+1; // }else if(2*i<=N) { // size[i]=size[2*i+1]+1; // }else { // size[i]=1; // } // } //It can be abbreviated as follows for(int i=N;i>=1;i--) {// size[i] = 1 + (2*i<=N?size[2*i]:0)+(2*i+1<=N?size[2*i+1]:0);//Size [i] < = n so no redundancy } } private static void initA() { a[0]=1; inv[0]=1;//Be sure to initialize for(int i=1;i<=N;i++) { //The factorial process may exceed int, so we need to take the remainder first a[i]=a[i-1]*i%mod; //The inverse element of i-factorial inv[i]=quickPow(a[i],mod-2); } //show2(a) } private static long dp() { //dp[i] refers to the number of small root stacks numbered I long [] d=new long[N+1]; for(int x=N;x>=1;x--) { if(2*x+1<=N) d[x]=C(size[x]-1,size[2*x])*d[2*x]%mod*d[2*x+1]%mod; else if(2*x<=N) d[x]=C(size[x]-1,size[2*x])*d[2*x]%mod; else d[x]=1; } return d[1]; } //Calculate the number of combinations static long C(int N,int lsize) { //c(n,lsize)=N!* quicikPow( (N-lsize)!,mod-2 ) * quickPow(lsize!,mod-2) return a[N]*inv[ lsize ]%mod*inv[ N-lsize ]%mod; } /** * @param a * @param y * @return * Fast solution to the y power of x */ private static long quickPow(long a, int n) { if(a==0) return 0; long ans=1; long x=a; while(n>0) { if((n&1)==1) ans=ans*x%mod; n>>=1; x=x*x%mod; } return ans; } private static void show(long[] d) { for(int i=N;i>=1;i--) { System.out.print(d[i]+" "); } System.out.println(); } private static void show2(int[] d) { for(int i=N;i>=1;i--) { System.out.print(d[i]+" "); } System.out.println(); } }