位运算与常用表达式的转换
刚刚学习LIS最长上升子序列的时候,网上找了一文,里面有个解法是用树状数组来优化的程序代码:
#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; }
请问里边的add函数和ask函数中for循环的那个x+=x&-x和x-=x&-x是什么意思?
能用非位运算表达式写吗?