开始不会树状数组维护修改区间max,所以用线段树。然后死调不出来,发现题解区都是树状数组,就换了个树状数组,然后就过了?!
求原因。
线段树40pts:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll MOD=1e9+7;
// head
const int N=1e6+5;int MAXN=0;
struct node
{
int pos,val,minn,maxn;
}a[N],b[N];
bool cmp(node p,node q) {return p.maxn<q.maxn;}
bool cmp1(node p,node q) {return p.val<q.val;}
bool cmp2(node p,node q) {return p.pos<q.pos;}
int dp[N];
int ls(int x) {return x<<1;}
int rs(int x) {return x<<1|1;}
struct Seg
{
int ans[N<<2];
void push_up(int dir)
{
ans[dir]=max(ans[ls(dir)],ans[rs(dir)]);
}
void modify(int dir,int l,int r,int x,int k)
{
if(l==x&&r==x) {ans[dir]=k;return ;}
int mid=(l+r)>>1;
if(x<=mid) modify(ls(dir),l,mid,x,k);
else modify(rs(dir),mid+1,r,x,k);
push_up(dir);
}
int query(int qx,int qy,int x,int y,int dir)
{
int sum=0;
if(qx<=x&&y<=qy) return ans[dir];
int mid=(x+y)>>1;
if(qx<=mid) sum=query(qx,qy,x,mid,ls(dir));
if(qy>mid) sum=max(sum,query(qx,qy,mid+1,y,rs(dir)));
return sum;
}
}tree;
void CDQ(int l,int r)
{
if(l==r) return ;
int mid=(l+r)>>1;
CDQ(l,mid);
sort(a+l,a+mid+1,cmp);
sort(a+mid+1,a+r+1,cmp1);
int i=l,j=mid+1;
while(j<=r)
{
while(i<=mid&&a[i].maxn<=a[j].val){
tree.modify(1,1,MAXN,a[i].val,dp[a[i].pos]);
i++;
}
dp[a[j].pos]=max(dp[a[j].pos],tree.query(1,a[j].minn,1,MAXN,1)+1);
j++;
}
for(int k=l;k<i;k++) tree.modify(1,1,MAXN,a[k].val,0);
sort(a+l,a+r+1,cmp2);
CDQ(mid+1,r);
}
signed main()
{
cin.tie(nullptr);
ios::sync_with_stdio(false);
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++) a[i].pos=i,dp[i]=1;
for(int i=1;i<=n;i++) {cin>>a[i].val;a[i].maxn=a[i].minn=a[i].val;MAXN=max(MAXN,a[i].val);}
for(int i=1;i<=m;i++) {
int x,y;cin>>x>>y;
a[x].minn=min(a[x].minn,y);
a[x].maxn=max(a[x].maxn,y);
}
CDQ(1,n);
int ans=0;
for(int i=1;i<=n;i++) ans=max(ans,dp[i]);
cout<<ans<<endl;
}
树状数组100pts:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll MOD=1e9+7;
// head
const int N=1e6+5;int MAXN=0;
struct node
{
int pos,val,minn,maxn;
}a[N],b[N];
bool cmp(node p,node q) {return p.maxn<q.maxn;}
bool cmp1(node p,node q) {return p.val<q.val;}
bool cmp2(node p,node q) {return p.pos<q.pos;}
int dp[N];
int c[N];
void modify(int x,int v)
{
for(;x<=MAXN;x+=x&(-x))
c[x]=max(c[x],v);
}
int ask(int x)
{
int ret=0;
for(;x;x-=x&(-x))
ret=max(c[x],ret);
return ret;
}
void clear(int x)
{
for(;x<=MAXN;x+=x&(-x))
c[x]=0;
}
void CDQ(int l,int r)
{
if(l==r) return ;
int mid=(l+r)>>1;
CDQ(l,mid);
sort(a+l,a+mid+1,cmp);
sort(a+mid+1,a+r+1,cmp1);
int i=l,j=mid+1;
while(j<=r)
{
while(i<=mid&&a[i].maxn<=a[j].val){
modify(a[i].val,dp[a[i].pos]);
i++;
}
dp[a[j].pos]=max(dp[a[j].pos],ask(1,a[j].minn)+1);
j++;
}
for(int k=l;k<i;k++) tree.modify(1,1,MAXN,a[k].val,0);
sort(a+l,a+r+1,cmp2);
CDQ(mid+1,r);
}
signed main()
{
cin.tie(nullptr);
ios::sync_with_stdio(false);
int n,m;cin>>n>>m;
for(int i=1;i<=n;i++) a[i].pos=i,dp[i]=1;
for(int i=1;i<=n;i++) {cin>>a[i].val;a[i].maxn=a[i].minn=a[i].val;MAXN=max(MAXN,a[i].val);}
for(int i=1;i<=m;i++) {
int x,y;cin>>x>>y;
a[x].minn=min(a[x].minn,y);
a[x].maxn=max(a[x].maxn,y);
}
CDQ(1,n);
int ans=0;
for(int i=1;i<=n;i++) ans=max(ans,dp[i]);
cout<<ans<<endl;
}