【bzoj1264】[AHOI2006]基因匹配Match 树状数组

题解:

一道比较简单的题目

容易发现状态数只有5*n个

而转移需要满足i1<i2;j1<j2

那么很明显是二维平面数点

暴力一点就是二维树状数组+map

5nlog^3 比较卡常

但是注意到我们的dp是保证了i1<i2的

所以本质是扫描线+树状数组

5nlogn

由于代码非常简单编译调试一遍过

代码:

 

#include <bits/stdc++.h>
using namespace std;
#define IL inline
#define rint register int
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
#define mid ((h+t)/2)
#define me(x) memset(x,0,sizeof(x))
#define lowbit(x) (x&(-x))
const int N=2e5;
int n,a[N],b[N],f[N][6],cnt[N];
char ss[1<<24],*A=ss,*B=ss; 
IL char gc()
{
  return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++; 
}
template<class T>IL void read(T &x)
{
  rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
  while (c=gc(),47<c&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f;
}
IL void maxx(int &x,int y)
{
  if (x<y) x=y;
}
struct sgt{
  int data[N];
  int query(int x)
  {
    int ans=0;
    while (x)
    {
      maxx(ans,data[x]);
      x-=lowbit(x);
    }
    return(ans);
  }
  void insert(int x,int y)
  {
    while (x<=n)
    {
      maxx(data[x],y);
      x+=lowbit(x);
    }
  }
}S;
int main()
{
  freopen("1.in","r",stdin);
  freopen("1.out","w",stdout);
  read(n); n*=5;
  rep(i,1,n) read(a[i]);
  rep(i,1,n) read(b[i]);
  rep(i,1,n)
    f[b[i]][++cnt[b[i]]]=i;
  int ans=0;
  rep(i,1,n)
    dep(j,5,1)
    {
      int kk=S.query(f[a[i]][j]-1)+1;
      S.insert(f[a[i]][j],kk);
      maxx(ans,kk);
    }
  cout<<ans<<endl; 
  return 0;
}

 

posted @ 2018-07-29 11:32  尹吴潇  阅读(135)  评论(0编辑  收藏  举报