//树状数组 //利用lowbit函数将区间划分为以二进制结尾的长度的小区间,然后利用这些小区间相加,减少时间复杂度 //树状数组的本质就是前缀和+可修改区间,求单点前缀和,如果是求某一的区间和,需要稍加修改,下面有类似例题,维护前缀和还有i*前缀和就可以 //也就是说树状数组就是更快一点的前缀和,但是比前缀和的功能要多,可维护的种类更广泛 //楼兰图腾 #include <bits/stdc++.h> #define int long long using namespace std; const int N=1e6+10,mod=1e9+7; string s; int n,t,a[N],f[N],res,num,ans,m,g[N],low[N],tr[N]; bool vis[N]; int lowbit(int x){ return x&-x; } void add(int x,int c) { for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=c; } int sum(int x) { int op=0; for(int i=x;i>=1;i-=lowbit(i)) op+=tr[i]; return op; } signed main() { std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++){ int y=a[i]; g[i]=sum(n)-sum(y); low[i]=sum(y-1); add(y,1); } memset(tr,0,sizeof tr); for(int i=n;i>=1;i--){ int y=a[i]; ans+=g[i]*(sum(n)-sum(y)); num+=low[i]*(sum(y-1)); add(y,1); } cout<<ans<<" "<<num<<endl; return 0; } //一个简单的整数问题 //区间加数,求单点值 //利用树状数组与差分 //用树状数组维护差分 #include <bits/stdc++.h> #define int long long using namespace std; const int N=1e6+10,mod=1e9+7; string s; int n,t,a[N],f[N],res,num,ans,m,tr[N]; bool vis[N]; int lowbit(int x){ return x&-x; } void add(int x,int c) { for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=c; } int sum(int x) { int op=0; for(int i=x;i>=1;i-=lowbit(i)) op+=tr[i]; return op; } signed main() { std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++) add(i,a[i]-a[i-1]); while(m--){ char s; int x,y,z; cin>>s; if(s=='C'){ cin>>x>>y>>z; add(x,z),add(y+1,-z); } else if(s=='Q'){ cin>>x; cout<<sum(x)<<endl; } } return 0; } //一个简单的整数问题2 //区间加+区间和 #include <bits/stdc++.h> #define int long long using namespace std; const int N=1e6+10,mod=1e9+7; string s; int n,t,a[N],f[N],res,num,ans,m,tr1[N],tr2[N]; bool vis[N]; int lowbit(int x){ return x&-x; } void add(int tr[],int x,int c) { for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=c; } int sum(int tr[],int x) { int op=0; for(int i=x;i>=1;i-=lowbit(i)) op+=tr[i]; return op; } int pre_sum(int x){ return sum(tr1,x)*(x+1)-sum(tr2,x); } signed main() { std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++){ int y=a[i]-a[i-1]; add(tr1,i,y),add(tr2,i,i*y); } while(m--){ char op; int l,r,d; cin>>op>>l>>r; if(op=='Q') cout<<pre_sum(r)-pre_sum(l-1)<<endl; else{ cin>>d; add(tr1,l,d),add(tr1,r+1,-d); add(tr2,l,d*l),add(tr2,r+1,-d*(r+1)); } } return 0; } //谜一样的牛 //从后向前找,假设现在的值是2,也就是从前到现在这个区间里面,这个牛的位置是第3小的牛 //如果有5头,x=2,也就是说有两头牛比他低,它就是第三小,也就是5-3=2,第2 #include <bits/stdc++.h> #define int long long using namespace std; const int N=1e6+10,mod=1e9+7; string s; int n,t,a[N],f[N],res,num,ans,m,tr[N]; bool vis[N]; int lowbit(int x){ return x&-x; } void add(int x,int c){ for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=c; } int sum(int x){ int op=0; for(int i=x;i>=1;i-=lowbit(i)) op+=tr[i]; return op; } signed main() { std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>n; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=n;i++) add(i,1); for(int i=n;i>=1;i--){ int y=a[i]+1; int l=0,r=n; while(l<r){ int mid=l+r>>1; if(sum(mid)>=y) r=mid; else l=mid+1; } f[i]=r; add(r,-1); } for(int i=1;i<=n;i++) cout<<f[i]<<" "; return 0; }
标签:return,树状,int,lowbit,cin,add,数组,op From: https://www.cnblogs.com/o-Sakurajimamai-o/p/17568434.html