专栏文章
树状数组
题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mir1aqi5
- 此快照首次捕获于
- 2025/12/04 14:07 3 个月前
- 此快照最后确认于
- 2025/12/04 14:07 3 个月前
树状数组-1
定点修改,区间查询
参考P3374
用前缀和来实现:
CPP#include<bits/stdc++.h>
using namespace std;
const int N=200000000;
int n,m,tmp,x,y,k,op;
int a[N];
unsigned long long ans;
int lowbit(int x)
{
return x&(-x);//取x的补码
}
void add(int x,int k)
{
for(int i=x;i<=n;i+=lowbit(i))//把受影响的前缀和进行更改
{
a[i]+=k;
}
}
int find(int l,int r)
{
for(int i=r;i;i-=lowbit(i))//先加上所有前缀和
{
ans+=a[i];
}
for(int i=l-1;i;i-=lowbit(i))//减去前面多余的
{
ans-=a[i];
}
return 0;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>tmp;
add(i,tmp);
}
for(int i=1;i<=m;i++)
{
cin>>op>>x;
if(op==1)
{
cin>>k;
add(x,k);
}
else
{
cin>>y;
ans=0;
find(x,y);
cout<<ans<<endl;
}
}
return 0;
}
区间修改,定点查询
参考P3368
用差分实现:
CPP#include<bits/stdc++.h>
using namespace std;
int n,m,tmp,x,y,k,op,pre;
int a[500007],num[500007];
long long ans;
int lowbit(int x)
{
return x&-x;
}
void add(int x,int k)
{
for(int i=x;i<=n;i+=lowbit(i))//修改差分
{
a[i]+=k;
}
}
void find(int r)
{
for(int i=r;i>=1;i-=lowbit(i))
{
ans+=a[i];
}
return ;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>num[i];
}
for(int i=1;i<=m;i++)
{
cin>>op;
if(op==1)
{
cin>>x>>y>>k;
add(x,k);
add(y+1,-k);//修改后变化的是x,y+1
}
else
{
cin>>x;
ans=0;
find(x);
cout<<num[x]+ans<<endl;
}
}
return 0;
}
逆序对
CPP#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;
int n,m,tmp,x,y,k;
char op;
int a[N],t[N],d[N];
int lowbit(int x)
{
return x&(-x);
}
bool cmp(int x,int y)
{
if(a[x]==a[y])
{
return x>y;
}
return a[x]>a[y];
}
void add(int x)
{
for(int i=x;i<=n;i+=lowbit(i))
{
t[i]++;
}
}
int sum(int x)
{
int res=0;
for(int i=x;i;i-=lowbit(i))
{
res+=t[i];
}
return res;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
d[i]=i;
}
sort(d+1,d+1+n,cmp);
long long ans=0;
for(int i=1;i<=n;i++)
{
add(d[i]);
ans+=sum(d[i]-1);
}
cout<<ans<<endl;
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...