首页 > 代码库 > HDU 5141
HDU 5141
这个题 LIS + 并查集的思想 + 链式前向星
要求找s(i,j)使i j 能有最长的LIS 。。。
做法是枚举每一个j 即终点 算 起点 的可能
无力吐槽了 bc 的时候写错了一个地方 导致TLE 后来幡然醒悟了
改了就a了
+++++++++++++++++++++++++++++++++++++++++++
不想说什么了 直接上代码
+++++++++++++++++++++++++++++++++++++++++++
#include <cstdio>#include <cmath>#include <algorithm>#include <iostream>#include <cstdlib>#include <string>#include <queue>#include <map>#include <stack>#include <cstring>#define CL(a,b) memset(a,b,sizeof(a))#define ll __int64#define TEST cout<<"TEST ***"<<endl;#define INF 0x7ffffff0#define MOD 1000000007using namespace std;typedef struct node{ int p,next;}N;N no[100010];int head[100010],cv;int num[100010];int fa[100010];int pi[100010];int so[100010],ct;int n;void inithead(){ CL(head,-1); cv=0;}void addnode(int s,int e){ no[cv].p=e;no[cv].next=head[s];head[s]=cv++;}void initfa(){ int i,j; for(i=0;i<=100000;i++)fa[i]=i;}int finr(int x){ if(fa[x]==x)return x; fa[x]=finr(fa[x]); return fa[x];}void unio(int x,int y){ int rx=finr(x); int ry=finr(y); fa[rx]=ry;}int bin(int s,int e,int v){ int m=(s+e)/2; if(so[m]>=v&&so[m-1]<v)return m; if(so[m]>v)return bin(s,m,v); return bin(m+1,e,v);}int main(){ while(scanf("%d",&n)!=EOF) { int i,j,a,p,v; initfa(); inithead(); so[0]=-1;ct=0; for(i=1;i<=n;i++) { scanf("%d",&a); num[i]=a; if(a>so[ct]) { ct++; so[ct]=a; addnode(ct,i); pi[i]=ct; } else { p=bin(0,ct,a); so[p]=a; addnode(p,i); pi[i]=p; } if(pi[i]!=1) { p=head[pi[i]-1]; while(p!=-1) { v=no[p].p; if(num[v]<a) { unio(i,v); break; } p=no[p].next; } } } ll rem=0,la=0,he; i=n; while(i>=1) { la++; if(pi[i]==ct) { he=finr(i); rem+=la*he; la=0; } i--; } printf("%I64d\n",rem); } return 0;}
HDU 5141
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。