![]() |
#2
叶纤2020-04-11 16:37
|

#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
#define rg register int
using namespace std;
int n;
int s[200005];
struct su{
int v,id; //按照权值为第一关键字保证算法正确性
inline bool operator <(su x){
if(v==x.v)return id>x.id; //按照序号从大到小可以保证所求为上升子序列
return v<x.v; //(针对标号)因为相同权值的数,前面的状态不能转移给后面
} //(针对标号)从大到小枚举就不会出现这种情况
}a[200005];
inline void add(int x,int y){
for(;x<=n;x+=x&-x) s[x]=max(s[x],y);
}
inline int ask(int x){
rg res=0;
for(;x>=1;x-=x&-x) res=max(s[x],res);
return res;
}
int main(){
cin>>n;
for(rg i=1;i<=n;++i)
cin>>a[i].v,a[i].id=i;
sort(a+1,a+n+1);
for(rg i=1;i<=n;++i)
add(a[i].id,ask(a[i].id)+1);
cout<<ask(n)<<endl;
return 0;
}
#include<cstdio>
#include<algorithm>
#define ll long long
#define rg register int
using namespace std;
int n;
int s[200005];
struct su{
int v,id; //按照权值为第一关键字保证算法正确性
inline bool operator <(su x){
if(v==x.v)return id>x.id; //按照序号从大到小可以保证所求为上升子序列
return v<x.v; //(针对标号)因为相同权值的数,前面的状态不能转移给后面
} //(针对标号)从大到小枚举就不会出现这种情况
}a[200005];
inline void add(int x,int y){
for(;x<=n;x+=x&-x) s[x]=max(s[x],y);
}
inline int ask(int x){
rg res=0;
for(;x>=1;x-=x&-x) res=max(s[x],res);
return res;
}
int main(){
cin>>n;
for(rg i=1;i<=n;++i)
cin>>a[i].v,a[i].id=i;
sort(a+1,a+n+1);
for(rg i=1;i<=n;++i)
add(a[i].id,ask(a[i].id)+1);
cout<<ask(n)<<endl;
return 0;
}
请问里边的add函数和ask函数中for循环的那个x+=x&-x和x-=x&-x是什么意思?
能用非位运算表达式写吗?