【线段树刷题小记】AcWing 242. 一个简单的整数问题|243. 一个简单的整数问题2|245. 你能回答这些问题吗|246. 区间最大公约数

242. 一个简单的整数问题

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define rg register
using namespace std;
typedef long long ll;
inline int sread()
{
    int x=0,f=1;char c=getchar();
    while(c>'9'||c<'0') {if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
    return f*x; 
}
const int maxn=5e5+10;
int a[maxn],x,y,k,n,m,ans,c[maxn];
char ops;
int lowbit(int x)
{
    return x&(-x);
}
void update(int x,int val)
{
    for(rg int i=x;i<=n;i+=lowbit(i)) c[i]+=val;
}
int getsum(int x)
{
    int sum=0;
    for(rg int i=x;i;i-=lowbit(i)) sum+=c[i];
    return sum;
}
int main()
{
    n=sread();  m=sread();
    for(rg int i=1;i<=n;++i)
    {
        a[i]=sread();
    }
    for(rg int i=1;i<=m;++i)
    {
        cin>>ops;
        if(ops=='C') 
        {
            x=sread();  y=sread();  k=sread();
            update(x,k); update(y+1,(-1)*k);
        }
        else if(ops=='Q')
        {
            x=sread();
            ans=a[x]+getsum(x);
            printf("%d\n",ans);
        }
    } 
    return 0;
}

243. 一个简单的整数问题2

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define rg register
using namespace std;
typedef long long ll;
inline ll sread()
{
    ll x=0,f=1;char c=getchar();
    while(c>'9'||c<'0') {if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
    return f*x; 
}
const ll maxn=5e5+10;
ll a[maxn],x,y,k,n,m,ans,c[3][maxn],sum[maxn];
char ops;
ll lowbit(ll x)
{
    return x&(-x);
}
void update(ll k,ll x,ll val)
{
    for(rg ll i=x;i<=n;i+=lowbit(i)) c[k][i]+=val;
}
ll getsum(ll k,ll x)
{
    ll sum=0;
    for(rg ll i=x;i;i-=lowbit(i)) sum+=c[k][i];
    return sum;
}
int main()
{
    n=sread();  m=sread();
    for(rg ll i=1;i<=n;++i)
    {
        a[i]=sread();
        sum[i]=sum[i-1]+a[i];
    }
    for(rg ll i=1;i<=m;++i)
    {
        cin>>ops;
        if(ops=='C') 
        {
            x=sread();  y=sread();  k=sread();
            update(1,x,k); update(1,y+1,(-1)*k);
            update(2,x,x*k);    update(2,y+1,(-1)*(y+1)*k);
        }
        else if(ops=='Q')
        {
            x=sread(); y=sread();
            ans=sum[y]+(y+1)*getsum(1,y)-getsum(2,y);
            ans-=sum[x-1]+x*getsum(1,x-1)-getsum(2,x-1); 
            printf("%lld\n",ans);
        }
    } 
    return 0;
}

245. 你能回答这些问题吗

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define rg register
using namespace std;
typedef long long ll;
inline int sread()
{
	int x=0,f=1;char c=getchar();
	while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();} 
	return f*x;
}
const int maxn=1000000;
struct node{
	int val;
};
node segtree[maxn*4];
int n,m,a[maxn];
void _build(int rt,int al,int ar)
{
	if(al==ar) 
	{
		segtree[rt].val=a[al];
		return ;
	}
	int m=(al+ar)>>1;
	_build(rt<<1,al,m);
	_build(rt*2+1,m+1,ar);
	segtree[rt].val = max(segtree[rt].val , segtree[rt<<1].val + segtree[rt*2+1].val );
	printf("rt= %d  segtree[].val= %d \n",rt,segtree[rt].val);
	getchar();
}
int _query(int rt,int al,int ar,int ql,int qr)
{
	if(al>qr||ar<ql) return 0;
	if(ql<=al&&qr>=ar)
	{
		return segtree[rt].val;
	}
	int m=(al+ar)>>1;
	return  max(segtree[rt].val , _query(rt<<1,al,m,ql,qr) + _query(rt*2+1,m+1,ar,ql,qr) );
}
void _update(int rt,int al,int ar,int x,int val)
{
	if(al==ar)
	{
		if(al==x) segtree[rt].val+=val;
		return ;
	}
	int m=(al+ar)>>1;
	if(x<=m) _update(rt<<1,al,m,x,val);
	else _update(rt*2+1,m+1,ar,x,val);
	segtree[rt].val = max(segtree[rt].val , segtree[rt<<1].val + segtree[rt*2+1].val );
	//printf("rt= %d  segtree[].val= %d \n",rt,segtree[rt].val);
	//getchar();
}
int ops,x,y;
int main()
{
	n=sread();	m=sread();
	for(rg int i=1;i<=n;++i)	a[i]=sread();
	_build(1,1,n);
	for(rg int i=1;i<=m;++i)
	{
		ops=sread();	x=sread();	y=sread();
		if(x>y) swap(x,y);
		if(ops==2)
			_update(1,1,n,x,y);
		else if(ops==1)
			cout<<_query(1,1,n,x,y)<<endl;
	}
	return 0;
}

246. 区间最大公约数

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define rg register
using namespace std;
typedef unsigned long long ull;
inline ull sread()
{
	ull x=0,f=1;char c=getchar();
	while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();} 
	return f*x;
}
const ull maxn=500010;
struct node{
	ull val,lazytag;
}t[maxn*4];
ull n,m,l,r,d;
char ops;
ull a[maxn];

inline ull gcd(ull a,ull b)
{
	if(b==0) return a;
	else return gcd(b,a%b);
}

void _pushdown(ull rt,ull al,ull ar)
{
	ull m=(al+ar)>>1;
	if(al!=ar && t[rt].lazytag!=0)
	{
		t[rt<<1].val+=t[rt].lazytag;
		t[rt*2+1].val+=t[rt].lazytag;
		t[rt<<1].lazytag+=t[rt].lazytag;
		t[rt*2+1].lazytag+=t[rt].lazytag;
		t[rt].lazytag=0;
	}
}

void _update(ull rt,ull al,ull ar,ull ql,ull qr,ull val)
{
	if(al>qr||ar<ql) return ;
	if(ql<=al&&qr>=ar)
	{
		t[rt].val+=val;
		t[rt].lazytag+=val;
		return ;
	}
	_pushdown(rt,al,ar);
	ull m=(al+ar)>>1;
	_update(rt<<1,al,m,ql,qr,val);
	_update(rt*2+1,m+1,ar,ql,qr,val);
	t[rt].val = gcd( t[rt<<1].val , t[rt*2+1].val );
}

void _build(ull rt,ull al,ull ar)
{
	t[rt].lazytag=0;
	if(al==ar)
	{
		t[rt].val=a[al];
		return ;
	}
	ull m=(al+ar)>>1;
	_build(rt<<1,al,m);
	_build(rt*2+1,m+1,ar);
	t[rt].val = gcd( t[rt<<1].val , t[rt*2+1].val );
}

ull _query(ull rt,ull al,ull ar,ull ql,ull qr)
{
	if(ar<ql||al>qr) return 0;
	if(ql<=al&&qr>=ar)
	{
		return t[rt].val;
	}
	_pushdown(rt,al,ar);
	ull m=(al+ar)>>1;
	return gcd( _query(rt<<1,al,m,ql,qr) , _query(rt*2+1,m+1,ar,ql,qr) );
}

int main()
{
	n=sread();	m=sread();
	for(rg ull i=1;i<=n;++i) a[i]=sread();
	_build(1,1,n);
	for(rg ull i=1;i<=m;++i)
	{
		ops=getchar();
		if(ops=='C')
		{
			l=sread();	r=sread();	d=sread();
			_update(1,1,n,l,r,d);
		}
		else if(ops=='Q')
		{
			l=sread();	r=sread();
			cout<< _query(1,1,n,l,r)<<endl;
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值