http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1319
这题给人的第一感觉就是最长上升子序列,按S排序,对B进行求解最长上升子序列,但是N太大
o(n^2)肯定不行,所以要用优化,我是用了线段数进行优化。
不是经常用类,这次用了一下,还是有很多小问题的,如果在函数内部静态申请一个局部变量对象
由于对象内有很大的数组,这样就相当于在函数所占用的栈区内申请了很大数组,没有语法错误,但c++是不允许它执行的
换成从堆区申请就好了,不过要记得delete否则会超内存
DP思想+线段树优化
代码:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<algorithm>
#define LL long long
using namespace std;
const int N=100005;
struct node
{
int x,y;
int index;
}man[N];
map<int,int>mt;
stack<int>st;
int Max[N],f[N];
class segTree
{
public:
segTree(int s,int e)
{
build(s,e);
}
private:
struct node
{
int l,r,k;
}tree[N*4];
public:
void build(int l,int r,int x=1)
{
tree[x].l=l;
tree[x].r=r;
tree[x].k=0;
if(l==r)
return ;
int mid=(l+r)>>1;
build(l,mid,(x<<1));
build(mid+1,r,((x<<1)|1));
}
void insert(int p,int k,int x=1)
{
if(Max[tree[x].k]<Max[k])
tree[x].k=k;
if(tree[x].l==tree[x].r)
return ;
if(p<=((tree[x].l+tree[x].r)>>1))
insert(p,k,(x<<1));
else
insert(p,k,((x<<1)|1));
}
int getMax(int l,int r,int x=1)
{
if(tree[x].l==l&&tree[x].r==r)
return tree[x].k;
int mid=(tree[x].l+tree[x].r)>>1;
if(r<=mid)
return getMax(l,r,(x<<1));
else if(l>mid)
return getMax(l,r,((x<<1)|1));
else
{
int k1=getMax(l,mid,(x<<1));
int k2=getMax(mid+1,r,((x<<1)|1));
return (Max[k1]>Max[k2])?k1:k2;
}
}
};
bool cmpx(node a,node b)
{
if(a.x==b.x)
return a.y<b.y;
return a.x<b.x;
}
bool cmpy(node a,node b)
{
if(a.y==b.y)
return a.x<b.x;
return a.y<b.y;
}
int main()
{
//freopen("data.in","r",stdin);
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
for(int i=1;i<=n;++i)
{
cin>>man[i].x>>man[i].y;
man[i].index=i;
}
sort(man+1,man+n+1,cmpy);
mt.clear();
int I=0;
for(int i=1;i<=n;++i)
if(i==1||man[i].y!=man[i-1].y)
mt[man[i].y]=(++I);
sort(man+1,man+n+1,cmpx);
memset(Max,0,sizeof(Max));
memset(f,-1,sizeof(f));
segTree *myTree = new segTree(0,I);
int s=0;
for(int i=1;i<=n;++i)
{
int l=mt[man[i].y];
int k=myTree->getMax(0,l-1);
Max[i]=Max[k]+1;
f[i]=k;
if(Max[i]>Max[s])
s=i;
st.push(i);
if(i==n||man[i].x!=man[i+1].x)
{
while(!st.empty())
{
int tmp=st.top();st.pop();
myTree->insert(mt[man[tmp].y],tmp);
}
}
}
delete myTree;
cout<<Max[s]<<endl;
while(f[s]!=0)
{
cout<<man[s].index<<" ";
s=f[s];
}
cout<<man[s].index<<endl;
if(T>0)
cout<<endl;
}
return 0;
}
浙公网安备 33010602011771号