前言
第七周周任务,树状数组之前学习过一些基础的,所以借着这次周任务,我正好可以掌握树状数组的高级操作,比如二维树状数组啥的。
ps:本文章是解题文章而不是学习文章,如需学习请移步?
周任务如下
目录
解题
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
using namespace std;
const int max_n=1<<16;
int C[max_n]={0};
//查询
int lowbit(int x){
return x&(-x);
}
int getsum(int n){
int sum=0;
for(int i=n;i>0;i-=lowbit(i)){
sum+=C[i];
}
return sum;
}
//更新
void updata(int n,int x){
for(int i=n;i<=max_n;i+=lowbit(i)){
C[i]+=x;
}
}
signed main(){
int t;
scanf("%d",&t);
for(int tt=1;tt<=t;tt++){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
updata(i,x);
}
printf("Case %d:\n",tt);
string s;
while(cin >> s){
if(s=="End") break;
int x,y;
scanf("%d%d",&x,&y);
if(s=="Query"){
if(x==1){
printf("%d\n",getsum(y));
}else
printf("%d\n",getsum(y)-getsum(x-1));
}else if(s=="Add"){
updata(x,y);
}else{
updata(x,-y);
}
}
memset(C,0,sizeof(C));
}
return 0;
}
#include<iostream>
#include<algorithm>
#define int long long
using namespace std;
const int maxn=500010;
pair<int,int> p[maxn];
int n;
int c[maxn];
int lowbit(int x){
return x&(-x);
}
void updata(int x,int k){
for(int i=k;i<=n;i+=lowbit(i)){
c[i]+=x;
}
}
int query(int k){
int sum=0;
for(int i=k;i>=1;i-=lowbit(i)){
sum+=c[i];
}
return sum;
}
signed main(){
while(cin >> n){
int sum=0;
if(n==0) break;
for(int i=1;i<=n;i++){
cin >> p[i].first;
p[i].second=i; //标号 --> 离散化
}
sort(p+1,p+n+1); //
for(int i=1;i<=n;i++){
c[i]=lowbit(i); //初始化个数
}
for(int i=1;i<=n;i++){
updata(-1,p[i].second);
sum+=query(p[i].second-1);
}
cout << sum << endl;
}
return 0;
}
2019牛客暑期多校训练营(第七场)E-Find the median
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define ll long long
#define sc(x) scanf("%d",&x);
#define pr(x) printf("%d",x);
#define ull unsigned long long
#define scll(x) scanf("%lld",&x);
#define prll(x) printf("%lld",x);
#define co(x) cout<<#x<<":"<<x<<endl;
const int maxn=400010;
ll n,cnt=0,tot=0;
ll x[maxn],y[maxn],l[maxn],r[maxn];
ll a1,b1,c1,a2,b2,c2,m1,m2;
ll z[maxn<<1],bit1[maxn<<1],bit2[maxn<<1];
ll lowbit(ll x){
return x&(-x);
}
void updata(ll a[],ll i,ll x){
while(i<=cnt){
a[i]+=x;
i+=lowbit(i);
}
}
ll getsum(ll a[],ll i){
ll ans=0;
while(i>0){
ans+=a[i];
i-=lowbit(i);
}
return ans;
}
void init(){
cin >> n;
cin >> x[1] >> x[2] >> a1 >> b1 >> c1 >> m1;
cin >> y[1] >> y[2] >> a2 >> b2 >> c2 >> m2;
for(int i=1;i<=n;i++){
if(i>2){
x[i]=(a1*x[i-1]+b1*x[i-2]+c1)%m1;
y[i]=(a2*y[i-1]+b2*y[i-2]+c2)%m2;
}
l[i]=min(x[i],y[i])+1;
r[i]=max(x[i],y[i])+1;
z[++cnt]=l[i];
z[++cnt]=r[i]+1;
}
sort(z+1,z+cnt+1);
cnt=unique(z+1,z+cnt+1)-z;
}
int main(){
init();
for(int i=1; i<=n ; i++){
tot=tot+r[i]-l[i]+1;
ll L=lower_bound(z+1,z+cnt,l[i])-z;
ll R=lower_bound(z+1,z+cnt,r[i]+1)-z;
updata(bit1,L,-l[i]);
updata(bit1,R,r[i]+1);
updata(bit2,L,1);
updata(bit2,R,-1);
ll left=1;
ll right=1e9;
while(left<right){
ll mid=(left+right)>>1;
ll q=upper_bound(z+1,z+cnt,mid)-z-1;
ll tmp=getsum(bit1,q)+getsum(bit2,q)*(mid+1);
if(tmp<(tot+1)>>1) left=mid+1;
else right=mid;
}
cout << left << endl;
}
return 0;
}
2019牛客暑期多校训练营(第七场)F-Energy stones
暂时没补
总结
树状数组算是我接触的第一个比较高级的数据结构,基本用法我了解的比较多,但是树状数组总是和别的知识来一起出题,比如思维、离散化等,还有二维树状数组,还有树状数组实现求最大值等,这些东西还是要靠自己理解和练习来加深学习。