HDU 3525(树状数组求解LCS)

Orienteering

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 203    Accepted Submission(s): 64

Problem Description
The Orienteering competition is coming soon!Now there are N players to participate in,each has his own cheering squad (lala dui) ,In order to ensure order and security competition,Each player's cheering squad can only send 2*M beautiful mm ,M mm from North Campus,M mm from South Campus(as known that HNU consists of South Campus and North Campus)。
In order to facilitate management , the mm from the same Campus must stay at the same side of the road which means there are two Sequences and each Sequence has equal number of mm .The day of the race,each side has many positions starting from the finishing line toward the starting line numbered for the 1,2,3. . . . up to 2*n*m positions,every mm has her own favorite position,however, when she finds her favorite position is occupied by other students, she has to go to the next position, until she finds a empty position(the cost time of this process is negligible)。
For example, there is a mm whose favorite position is 3,when she goes to the position 3,there has a people over there,so she goes to the next position 4,however ,still has a people there ,until she gets the position 6 where no one occupies this position at present,so she`s position is 6,when all the people find their positions ,the teacher for the competition comes ,he finds that there are still some empty positions ,then he orders that all people move closer to the finishing line which can not change the relative positions of each mm at the both side,so finally their positon number is from 1 to n*m,now we get two sequence A,B A[i] means the mm on the ith position of this side support the player A[i],B[i] means the mm on the ith position of the opposite side support the player B[i].
Now the teacher has Picking a speaker , the mm supporting different players must wear different clothes, but those who support the same player should wear the same clothes. In order to make the venue more harmonious visual effect,to choose two sequence (A[c[1]],A[c[2]],......A[c[len]]) (B[d[1]],B[d[2]],.....B[d[len]]),A[c[i]]=B[d[i]] (1=i<=len) The teacher want to know the max len,can you help us?Namely, you should find the max len such that there exists two identical subsequence with len elements in A and B respectively(these two subsequence need not to be continuous).
 

 

Input
The first line of input should give the number of cases, T (at most 20).the first line of each case has two numbers n,m(1<=n<=10000,1<=m<=10)n represent the number of players,numbers from 1 to n ,m represent the number of mm of each player`s cheering squad,The next two lines,each with n*m*2 numbers,the i*2-1 number means the ith mm`s supported player number v[i](1<=v[i]<=n),the i*2 number means the ith mm`s faviourite positionw[i](1<=w[i]<=m*n), we set the mm number i is earlier than the mm number j when (i<j).
 

 

Output
For each case, output should be one line containing "Case #x: ",then flollow a number ,the max len.
 

 

Sample Input
   
   
   
   
1 3 2 1 3 1 4 3 2 2 5 2 2 3 1 3 1 1 4 2 2 3 1 2 4 1 3
 

 

Sample Output
   
   
   
   
Case #1: 4
Hint
After the operation the A sequence is: 3 3 1 1 2 2 While The B sequence is : 3 2 3 1 2 1 The most longest common sequence is 3 3 1 1 so the len is 4.

刚刚接触树状数组,不会写

参考了大牛的代码:

#include <stdio.h> #include <string.h> #define max(a,b) (a>b?a:b) const int maxn = 200010; int next[maxn],tree[maxn]; int ff[maxn][12],f[maxn]; int lowbit(int t) { return t&-t; } void change(int pos , int num,int n) //修改 { while (pos<=n) { tree[pos] = max(num,tree[pos]); pos += lowbit(pos); } } int ask(int end)//查询 { int sum = 0; while(end > 0) { sum = max(sum,tree[end]); end -= lowbit(end); } return sum; } int n,m; int str1[maxn],str2[maxn],ch; void dp() { memset(tree,0,sizeof(tree)); int i,j,k; int maxres=0; for (i=1;i<=n*m;i++) for (j=m-1;j>=0;j--) { k=ff[str1[i]][j]; int t=ask(k-1)+1; maxres=max(maxres,t); change(k,t,n*m); } printf("%d/n",maxres); } int main() { int t,i,x,k,j,cas; scanf("%d",&t); cas = 0; while (t--) { scanf("%d%d",&n,&m); for (i=0;i<2*n*m+10;i++) { next[i] = i+1; str1[i] = 0; } for(i=0;i<n*m;i++) { scanf("%d%d",&ch,&x); k = x; while(str1[k] != 0) k = next[k]; str1[k] = ch; j = k; k = x; while(k!=j) { int temp = next[k]; next[k] = next[j]; k = temp; } } k=i=1; while (k<=n*m) { while (str1[i]==0) i++; str1[k++]=str1[i++]; } for (i=0;i<2*n*m+10;i++) { next[i] = i+1; str2[i] = 0; } for (i=0;i<n*m;i++) { scanf("%d%d",&ch,&x); k = x; while(str2[k] != 0) k = next[k]; str2[k] = ch; j = k; k = x; while(k!=j) { int temp = next[k]; next[k] = next[j]; k = temp; } } k=i=1; while (k<=n*m) { while (str2[i]==0) i++; str2[k++]=str2[i++]; } for(i=1;i<=n;i++) f[i] = 0; for(i=1;i<=n*m;i++) ff[str2[i]][f[str2[i]]++] = i; //记录位置? printf("Case #%d: ",++cas); dp(); } return 0; }

你可能感兴趣的:(tree,Security,input,each,output,Numbers)