B Test Instructions: Zyb in the hike, and the students play a "digital bomb" game: by the host in the mind of a [1,n][1,n] in the number XX, and then the players take turns to guess a number, if a player just guessed xx is calculated negative, Otherwise the host will tell the audience that the current number and XX ratio is large or small, and then guess the range will be correspondingly reduced, the beginning of the range is [1,n][1,n]. Each player can only guess in the legal range. Now assume that only two people are playing this game, and two people have already known the last xx, if two people have to adopt the optimal strategy. X \in [1,n]x∈[1,n] is the number of XX wins.
Idea: When n is odd, for example 5:1 2 3 4 5. Found only when the x==3 when the initiator will lose (can always follow the initiator on the 3 symmetry point selection) then x==2 (the initiator guess 4, the only one can guess 1 | | 3 are lost) | | 4 (similar) | | 1 (the initiator direct guess 2 to lose) | | 5 (similar)
So when n is even, for example 4:1 2 3 4. Current x== 1 | | 4 o'clock to win, when x==2, the initiator guess 4 then become an odd situation, so has always been the initiator to win
Code slightly ...
C Test Instructions: Zyb has a permutation p, but he only remembers the inverse logarithm of each prefix interval in P, and now he asks you to restore the arrangement.
(I,J) (I < J) (I,J) (I<J) is called a pair of inverse pairs when and only if Ai>aj
The given AI is the inverse logarithm of the prefix interval [1,i], which directly says a set of examples
Subscript 1 2 3 4 5 6
AI 0 1 1 4 8 10
Full Rank 5 3 6 2 1 4
It is easy to find that the AI from the back forward, can know the current number in the [1,i] interval has several numbers larger than it ==a[i]-a[i-1];
10-8=2; the current [1,6] interval has 2 numbers larger than it, then anw[6]=4;
8-4=4; The current [1,5] interval has four numbers (6,5,3,2) larger than it, 4 have been selected, then anw[5]=1;
4-1=3; the current [1,4] interval has three numbers (6,5,3) larger than it, 1,4 has been selected, anw[4]=2;
1-1=0; The current [1,3] interval has 0 numbers larger than it, 1,2,4 has chosen, anw[3]=6;
1-0=1; The current [up] interval has 1 numbers larger than it, 1,2,4,6 has been selected, anw[2]=3;
1-0=0; The current [0] interval has a larger number than it, 1,2,3,4,6 has chosen, anw[1]=5.
That is, using a line tree or a tree array to maintain the small K. k=i-(A[i]-a[i-1]);
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include < string> #include <vector> #include <ctime> #include <queue> #include <set> #include <map > #include <stack> #include <cmath> #define MST (SS,B) memset ((ss), (b), sizeof (SS)) #define MAXN 0x3f3f3f3f #pragma COMMENT (linker, "/stack:102400000,102400000") typedef long long ll; #define INF (1ll<<60) -1using Namespace Std;int n;int a[50010],tr[200010],anw[50010];void build (int root,int l,int R) {if (l==r) {tr[root]=1; return; } int mid= (L+R) >>1; Build (Root*2,l,mid); Build (Root*2+1,mid+1,r); TR[ROOT]=TR[ROOT*2]+TR[ROOT*2+1];} int query (int root,int l,int r,int k) {if (l==r) {return l; } int mid= (L+R) >>1; if (tr[root*2]>=k) return query (ROOT*2,L,MID,K); else return query (root*2+1,mid+1,r,k-tr[root*2]);} void update (int pos,int v,int root,int l,int R) {if (l==r) {tr[root]=v; Return; } int mid= (L+R) >>1; if (pos>mid) update (POS,V,ROOT*2+1,MID+1,R); else update (POS,V,ROOT*2,L,MID); TR[ROOT]=TR[ROOT*2]+TR[ROOT*2+1];} int main () {int T; scanf ("%d", &t); while (t--) {MST (a,0); MST (anw,0); scanf ("%d", &n); Build (1,1,n); for (int i=1;i<=n;i++) scanf ("%d", &a[i]); for (int i=n;i>=1;i--) {int x=a[i]-a[i-1]; Anw[i]=query (1,1,n,i-x); Update (ANW[I],0,1,1,N); } for (int i=1;i<=n;i++) {if (i==1) printf ("%d", anw[i]); else printf ("%d", anw[i]); } printf ("\ n"); } return 0;}
D Test Instructions: Zyb has a tree of n nodes, and now he wants you to find out the number of points from each point that do not exceed k at each point.
The distance between the two points (x, y) on the tree is defined as the number of edges passed by the shortest path on the two point tree, and the XOR of the answer of the output n points.
Idea: The first time Dfs is looking for the current node to walk down the length of <=k Num. The second time Dfs is looking for the current node to walk up the length of <=k Num.
The first time the direct search can be, the second two times to take ANW, the former node is V, the current node's father is X, think carefully, to find the current node up NUM, is not can be divided into
1. Num, the brother of V, is the child node of Father X 2. Find the ancestor of Father X to num of x-length <=k-1
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include < string> #include <vector> #include <ctime> #include <queue> #include <set> #include <map > #include <stack> #include <cmath> #define MST (SS,B) memset ((ss), (b), sizeof (SS)) #define INF 0x3f3f3f3f# Define MAX 500010#pragma COMMENT (linker, "/stack:102400000,102400000") typedef long long ll; #define INF (1LL<<60)- 1using namespace Std;int n,k,a,b,tot;int head[max];struct node{int to,next;} edge[max];void Add (int u,int v) {edge[tot].to=v;////Current side u->v edge[tot].next=head[u];///////Connect the previous edge of the U node Head[u] =tot++;} int son[max][15],pre[max][15],anw[max];void init () {MST (HEAD,-1); MST (son,0); MST (pre,0); MST (anw,0); tot=0;} void DFS (int x) {son[x][0]=1; for (int i=head[x];i!=-1;i=edge[i].next) {int v=edge[i].to; DFS (v); for (int j=1;j<=k;j++) son[x][j]+=son[v][j-1]; }}void DFS1 (int x) {///pre[x][0]=1; for (int i=0;i<=k;i++) anw[x]+= (Son[x][i]+pre[x][i]); for (int i=head[x];i!=-1;i=edge[i].next) {int v=edge[i].to; for (int j=1;j<13;j++) pre[v][j]+= (pre[x][j-1]); pre[v][1]++; for (int j=2;j<13;j++) pre[v][j]+= (son[x][j-1]-son[v][j-2]); DFS1 (v); }}int Main () {int T; scanf ("%d", &t); while (t--) {init (); scanf ("%d%d%d%d", &n,&k,&a,&b); for (int i=2;i<=n;i++) {ll w= (LL) a*i+b)% (i-1) +1; Add ((int) w,i); DFS (1);D FS1 (1); /*for (ll i=1;i<=n;i++) cout<<son[i][k]<< ""; cout<<endl; for (ll i=1;i<=n;i++) {for (ll j=0;j<=k;j++) {cout<<pre[i][j]<< ""; } cout<<endl; }*/int ans=0; for (int i=1;i<=n;i++) ans^=anw[i]; printf ("%d\n", ans); } return 0;}
Bestcoder Round #65 B C D | | HDU 5591 5592 5593