切记不要加任何文件读写, 本次比赛暂不支持ifndef ONLINE_JUDGE。请互相转告。评测机是linux
是个富有诗意的男孩。在他居住的小镇上,有 n个村庄,由 n-1条道路连接着。这里的生活和谐而又宁静。
有一天 tty偶然阅读到一篇杂志上的文章《阳光下的向日葵》,深受感动。特别是其中一位小女孩的故事让他记忆犹新。 于是他买来葵花籽,决定也像那位小女孩一样,给村民播种向日葵,把美丽和阳光带给村庄里的每一个人。
于是 tty决定在每次播种前选择两个村庄,然后从其中一个村庄出发,在这两个村庄的道路上的每一个村庄(包括起始点)种上一颗向日葵,在编号 i的村庄播种在可以长出 wi个葵花籽,而且向日葵受到天神 Owaski的保护,在生长过程中不会被人采摘。
若干天后,待到向日葵成熟时,tty又会以相同的路径去采摘那些向日葵上的葵花籽, 无论是否采摘,每一次播种的向日葵都会在下一次播种前死亡。
但是有轻微强迫症的他,不会采摘比他采摘的上一朵葵花籽相等或者更少的向日葵。
而tty并不知道这些数据,只能凭着感觉开始采摘,他想在更多的向日葵上采摘葵花籽,你能告诉他可以最多采摘的向日葵棵数吗?
题解:n个点n-1条边显然是一棵树嘛,所以每个询问求的是树上两点之间权值序列的LIS。
考场上我先是转有根树,求LCA然后暴力找路径nlogn求LIS(其实不需要这么麻烦),结果爆0了。
正确的姿势应该是离线算法,也就是预处理出答案ans[i][j],询问就O(1)输出。
首先枚举每个点,DFS求出这个点与其它点的LIS。这就是加点地求LIS。如果这个点的权值大于栈顶元素的话直接压栈更新答案。否则二分查找第一个权值大于等于它的并将其替换再维护答案。回溯回来要记得改回。这样的时间复杂度是O(n^2logn+Q)的。记得无向图边数要乘2。
%%%__debug大神。
#include<cstdlib> #include<cstdio> #include<algorithm> #include<cstring> #include<vector> #define INF 0x7fffffff/10 #define x first #define y second using namespace std; const int MAXN=4002; int first[MAXN],next[MAXN],w[MAXN],e=0,v[MAXN],n,q=0,f[MAXN]; int top=0,ans[MAXN][MAXN],d[MAXN]; struct point{ int x,y; point(int x=0,int y=0):x(x),y(y){} bool operator <(const point& rhs)const {return x<rhs.x;} }sta[MAXN]; void add(int a,int b) { e++;next[e]=first[a];first[a]=e;v[e]=b; } void dfs(int u,int fa,int from,int last) { for(int i=first[u];i!=-1;i=next[i]) { int to=v[i],ty=0,lc,la,lb,anss=last; if(to==fa)continue; if(from==2&&to==7) to=7; if(w[to]>sta[top].x) { anss=max(anss,top+1); f[to]=++top; sta[top].y=to; sta[top].x=w[to]; ty=1; } else { int k=lower_bound(sta+1,sta+top+1,point(w[to],to))-sta; f[to]=k; anss=max(anss,k); lc=k;la=sta[k].x;lb=sta[k].y; sta[k].x=w[to]; sta[k].y=to; } ans[from][to]=anss; dfs(to,u,from,anss); if(ty)top--; else { sta[lc].x=la; sta[lc].y=lb; } } } int main() { freopen("B.in","r",stdin); freopen("B.out","w",stdout); scanf("%d",&n); for(int i=0;i<=n;i++)first[i]=-1; for(int i=1;i<n;i++) { int a,b; scanf("%d %d",&a,&b); add(a,b); add(b,a); } for(int i=1;i<=n;i++)scanf("%d",&w[i]); for(int i=1;i<=n;i++) { top=1; ans[i][i]=1; sta[top].y=i; sta[top].x=w[i]; dfs(i,-1,i,1); } scanf("%d",&q); for(int i=1;i<=q;i++) { int a,b; scanf("%d %d",&a,&b); printf("%d\n",ans[a][b]); } return 0; }