算法记录

离散化

int a[N];
vectortmp;
for(int i=0;i
#include
#include
#include
using namespace std;
int tree[500010],rank[500010],n;
long long ans; 
struct point
{
    int num,val;
}a[500010];
inline bool cmp(point q,point w)
{
    if(q.val==w.val)
        return q.num

树状数组

void add(int p, int x){ //给位置p增加x
    while(p <= n) sum[p] += x, p += p & -p;
}
int ask(int p){ //求位置p的前缀和
    int res = 0;
    while(p) res += sum[p], p -= p & -p;
    return res;
}
int range_ask(int l, int r){ //区间求和
    return ask(r) - ask(l - 1);
}

线段树

#include
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5+5;
struct tree{
	int l,r;
	ll val,add;	
}t[maxn*4];
ll a[maxn];
// 建树 
void build(int p,int l,int r)
{	// 以p为编号的节点维护的区间为l到r
	t[p].l=l;t[p].r=r;
	if(l==r) 
	{
		t[p].val=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	t[p].val=t[p<<1].val+t[p<<1|1].val;
}
void spread(int p)
{	// 如果懒标记不为0,就将其下传,修改左右儿子维护的值
	if(t[p].add)
	{
		// 修改val:在区间查询要用到 
		t[p<<1].val += t[p].add*(t[p<<1].r-t[p<<1].l+1);
		t[p<<1|1].val += t[p].add*(t[p<<1|1].r-t[p<<1|1].l+1);
		t[p<<1].add += t[p].add;
		t[p<<1|1].add += t[p].add;
		t[p].add=0; // 下传之后将该节点的懒标记清0
	}
}
// 区间修改 
void change(int p,int x,int y,ll z)
{	//修改的区间覆盖了当前节点时,我们就把这个区间给修改,并打上懒标记
	if(x<=t[p].l && y>=t[p].r)
	{
		t[p].val += z*(t[p].r-t[p].l+1);
		t[p].add += z;
		return ;
	}
	spread(p); // 到这里是没有覆盖的,所以要标记下放 
	int mid=(t[p].l+t[p].r)>>1;
	if(x<=mid) change(p<<1,x,y,z);//如果要修改的区间覆盖了左儿子,就修改左儿子
	if(y>=mid+1) change(p<<1|1,x,y,z);
	t[p].val = t[p<<1].val + t[p<<1|1].val;
}
//区间查询 
ll ask(int p,int x,int y)
{
	if(x<=t[p].l && y>=t[p].r) return t[p].val;	//恰好覆盖 
	spread(p);	
	int mid=(t[p].l+t[p].r)>>1;
	ll ans=0;
	if(x<=mid) ans += ask(p<<1,x,y);
	if(y>=mid+1) ans += ask(p<<1|1,x,y);
	return ans;
}
void show()
{
	for(int p=1;t[p].val>0;p++) 
	{
		printf("(%d %d) val=%d add=%d\n",t[p].l,t[p].r,t[p].val,
		t[p].add);
	} 
	puts(""); 
}
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	build(1,1,n);
	while(m--)
	{
		ll q,x,y,k;
		cin>>q>>x>>y;
		if(q==1)
		{
			cin>>k;
			change(1,x,y,k);
		}
		else
		{
			cout<

你可能感兴趣的:(算法记录)