算法竞赛模板(数据结构)

尽量不要全局long long
尽量不要全局long long
尽量不要全局long long
尽量不要全局long long
尽量不要全局long long
尽量不要全局long long

目录

  • 分块
  • 线段树
    • 单点修改,区间查值
    • 区间修改,区间查值
      • 例题

分块

算法竞赛模板(数据结构)_第1张图片
算法竞赛模板(数据结构)_第2张图片

const int N=1e5+10,M=350;
int n,m;
int len;//len=sqrt(n)时间最优 
int a[N];
long long b[M],s[M];
//a表示数据数组,b记录每个块的整体赋值情况(懒标记),s块内元素和
int get(int x)//属于哪个块 
{
	return (x-1)/len;
} 
void modify(int l,int r,int val)
{
	if(get(l)==get(r))
	{
		rep(i,l,r)a[i]+=val,s[get(i)]+=val;
	}
	else
	{
		int i=l,j=r;
		while(get(i)==get(l))a[i]+=val,s[get(i)]+=val,i++;
		while(get(j)==get(r))a[j]+=val,s[get(j)]+=val,j--;
		rep(k,get(i),get(j))s[k]+=val*len,b[k]+=val;
	}
}
long long query(int l,int r)
{
	long long res=0;
	if(get(l)==get(r))
	{
		rep(i,l,r)res+=a[i]+b[get(i)];
	}
	else
	{
		int i=l,j=r;
		while(get(i)==get(l))res+=a[i]+b[get(i)],i++;
		while(get(j)==get(r))res+=a[j]+b[get(j)],j--;
		rep(k,get(i),get(j))res+=s[k];
	}
	return res;
}
void solve()
{
	cin>>n>>m;
	len=sqrtl(n);//均值不等式
	rep(i,1,n)
	{
		cin>>a[i];
		s[get(i)]+=a[i];	
	} 
	while(m--)
	{
		char op;
		cin>>op;
		if(op=='C')
		{
			int l,r,x;
			cin>>l>>r>>x;
			modify(l,r,x);
		}
		else 
		{
			int l,r;
			cin>>l>>r;
			cout<<query(l,r)<<endl;
		}
	}
}

线段树

单点修改,区间查值

#include 
using namespace std;
const double pi = acos(-1);
const double eps=1e-7;
const int base=131;
#define YES cout<<"YES"<<endl
#define NO cout<<"NO"<<endl
#define x first
#define y second
#define int long long//高精度关掉此 
#define LL long long
#define ull unsigned long long
#define lb long double
#define pb push_back
#define endl '\n'//交互题删掉此 
#define all(v) (v).begin(),(v).end()
#define PII pair<int,int>
#define rep(i,x,n) for(int i=x;i<=n;i++)
#define dwn(i,n,x) for(int i=n;i>=x;i--)
#define ll_INF 0x7f7f7f7f7f7f7f7f
#define INF 0x3f3f3f3f
#define io ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
int Mod(int a,int mod){return (a%mod+mod)%mod;}
int lowbit(int x){return x&-x;}//最低位1及其后面的0构成的数值
int qmi(int a, int k, int p){int res = 1 % p;while (k){if (k & 1) res = Mod(res * a , p);a = Mod(a * a , p);k >>= 1;}return res;}
int inv(int a,int mod){return qmi(a,mod-2,mod);}
int lcm(int a,int b){return a*b/__gcd(a,b);}
const int N=5e5+10;
int n,m;
struct node
{
	int l,r;
	int val;
}tr[N<<2];
int a[N];
void push_up(int u)
{
	tr[u].val=tr[u<<1].val+tr[u<<1|1].val;
}
void build(int k,int l,int r)
{
	tr[k].l=l,tr[k].r=r;
	if(l==r)
	{
		tr[k].val=a[l];
		return;
	}
	int mid=l+r>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
	push_up(k);
}
void modify(int k,int l,int r,int pos,int val)
{
	if(l==r)
	{
		tr[k].val+=val;
		return;
	}
	int mid=l+r>>1;
	if(pos<=mid)modify(k<<1,l,mid,pos,val);
	else modify(k<<1|1,mid+1,r,pos,val);
	push_up(k);
}
int query(int k,int l,int r,int x,int y)
{
	if(x>r||y<l)return 0;
	if(x<=l&&y>=r)return tr[k].val;
	int mid=l+r>>1;
	int res=0;
	if(x<=mid)res+=query(k<<1,l,mid,x,y);
	if(y>=mid+1)res+=query(k<<1|1,mid+1,r,x,y);
	return res;
}
void solve()
{
	cin>>n>>m;
	rep(i,1,n)cin>>a[i];
	build(1,1,n);
	while(m--)
	{
		int op;
		cin>>op;
		if(op==1)
		{
			int x,k;
			cin>>x>>k;
			modify(1,1,n,x,k);
		}
		else
		{
			int x,y;
			cin>>x>>y;
			cout<<query(1,1,n,x,y)<<endl;
		}
	}
}
signed main()
{
    io;
    int _;_=1;
    //cin>>_;
    while(_--)solve();
    return 0;

}

区间修改,区间查值

#include 
using namespace std;
const double pi = acos(-1);
const double eps=1e-7;
const int base=131;
#define YES cout<<"YES"<<endl
#define NO cout<<"NO"<<endl
#define x first
#define y second
#define int long long//高精度关掉此 
#define LL long long
#define ull unsigned long long
#define lb long double
#define pb push_back
#define endl '\n'//交互题删掉此 
#define all(v) (v).begin(),(v).end()
#define PII pair<int,int>
#define rep(i,x,n) for(int i=x;i<=n;i++)
#define dwn(i,n,x) for(int i=n;i>=x;i--)
#define ll_INF 0x7f7f7f7f7f7f7f7f
#define INF 0x3f3f3f3f
#define io ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
int Mod(int a,int mod){return (a%mod+mod)%mod;}
int lowbit(int x){return x&-x;}//最低位1及其后面的0构成的数值
int qmi(int a, int k, int p){int res = 1 % p;while (k){if (k & 1) res = Mod(res * a , p);a = Mod(a * a , p);k >>= 1;}return res;}
int inv(int a,int mod){return qmi(a,mod-2,mod);}
int lcm(int a,int b){return a*b/__gcd(a,b);}
const int N=5e5+10;
int n,m;
struct node
{
	int l,r;
	int lz;
	int val;
}tr[N<<2];
int a[N];
void push_up(int k)
{
	tr[k].val=tr[k<<1].val+tr[k<<1|1].val;
}
void push_down(int k,int l,int r)
{
	if(tr[k].lz)
	{
		int mid=l+r>>1;
		tr[k<<1].lz+=tr[k].lz;
		tr[k<<1|1].lz+=tr[k].lz;
		tr[k<<1].val+=tr[k].lz*(mid-l+1);
		tr[k<<1|1].val+=tr[k].lz*(r-mid);
		tr[k].lz=0;
	}
}
void build(int k,int l,int r)
{
	tr[k].l=l,tr[k].r=r;
	if(l==r)
	{
		tr[k].val=a[l];
		return;
	}
	int mid=l+r>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
	push_up(k);
}
void modify(int k,int l,int r,int x,int y,int p)
{
	if(x<=l&&y>=r)
	{
		tr[k].val+=(r-l+1)*p;
		tr[k].lz+=p;
		return;
	}
	push_down(k,l,r);
	int mid=l+r>>1;
	if(x<=mid)modify(k<<1,l,mid,x,y,p);
	if(y>=mid+1)modify(k<<1|1,mid+1,r,x,y,p);
	push_up(k);
}
int query(int k,int l,int r,int x,int y)
{
	if(x<=l&&y>=r)return tr[k].val;
	push_down(k,l,r);
	int mid=l+r>>1;
	int res=0;
	if(x<=mid)res+=query(k<<1,l,mid,x,y);
	if(y>=mid+1)res+=query(k<<1|1,mid+1,r,x,y);
	return res;
}
void solve()
{
	cin>>n>>m;
	rep(i,1,n)cin>>a[i];
	build(1,1,n);
	while(m--)
	{
		int op;
		cin>>op;
		if(op==1)
		{
			int x,y,k;
			cin>>x>>y>>k;
			modify(1,1,n,x,y,k);
		}
		else
		{
			int x,y;
			cin>>x>>y;
			cout<<query(1,1,n,x,y)<<endl;
		}
	}
}
signed main()
{
    io;
    int _;_=1;
    //cin>>_;
    while(_--)solve();
    return 0;

}

例题

将某区间每一个数乘上 x
将某区间每一个数加上 x
求出某区间每一个数的和

#include 
using namespace std;
const double pi = acos(-1);
const double eps=1e-7;
const int base=131;
#define YES cout<<"YES"<<endl
#define NO cout<<"NO"<<endl
#define x first
#define y second
#define int long long//高精度关掉此 
#define LL long long
#define ull unsigned long long
#define lb long double
#define pb push_back
#define endl '\n'//交互题删掉此 
#define all(v) (v).begin(),(v).end()
#define PII pair<int,int>
#define rep(i,x,n) for(int i=x;i<=n;i++)
#define dwn(i,n,x) for(int i=n;i>=x;i--)
#define ll_INF 0x7f7f7f7f7f7f7f7f
#define INF 0x3f3f3f3f
#define io ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
int Mod(int a,int mod){return (a%mod+mod)%mod;}
int lowbit(int x){return x&-x;}//最低位1及其后面的0构成的数值
int qmi(int a, int k, int p){int res = 1 % p;while (k){if (k & 1) res = Mod(res * a , p);a = Mod(a * a , p);k >>= 1;}return res;}
int inv(int a,int mod){return qmi(a,mod-2,mod);}
int lcm(int a,int b){return a*b/__gcd(a,b);}
const int N=1e5+10;
int n,m,p;
struct node
{
	int l,r;
	int lz_add;
	int lz_mul;
	int val;
}tr[N<<2];
int a[N];
void push_up(int k)
{
	tr[k].val=(tr[k<<1].val+tr[k<<1|1].val)%p;
}
void push_down(int k,int l,int r)
{
	int mid=l+r>>1;
	tr[k<<1].lz_add=(tr[k<<1].lz_add*tr[k].lz_mul+tr[k].lz_add)%p;
	tr[k<<1|1].lz_add=(tr[k<<1|1].lz_add*tr[k].lz_mul+tr[k].lz_add)%p;
	tr[k<<1].lz_mul=(tr[k<<1].lz_mul*tr[k].lz_mul)%p;
	tr[k<<1|1].lz_mul=(tr[k<<1|1].lz_mul*tr[k].lz_mul)%p;
	tr[k<<1].val=(tr[k<<1].val*tr[k].lz_mul+tr[k].lz_add*(mid-l+1))%p;
	tr[k<<1|1].val=(tr[k<<1|1].val*tr[k].lz_mul+tr[k].lz_add*(r-mid))%p;
	tr[k].lz_mul=1;
	tr[k].lz_add=0;
}
void build(int k,int l,int r)
{
	tr[k].l=l,tr[k].r=r,tr[k].lz_mul=1;
	if(l==r)
	{
		tr[k].val=a[l]%p;
		return;
	}
	int mid=l+r>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
	push_up(k);
}
void modify_mul(int k,int l,int r,int x,int y,int val)
{
	if(x<=l&&y>=r)
	{
		tr[k].lz_add=(tr[k].lz_add*val)%p;
		tr[k].lz_mul=(tr[k].lz_mul*val)%p;
		tr[k].val=(tr[k].val*val)%p;
		return;
	}
	push_down(k,l,r);
	int mid=l+r>>1;
	if(x<=mid)modify_mul(k<<1,l,mid,x,y,val);
	if(y>=mid+1)modify_mul(k<<1|1,mid+1,r,x,y,val);
	push_up(k);
}
void modify_add(int k,int l,int r,int x,int y,int val)
{
	if(x<=l&&y>=r)
	{
		tr[k].lz_add=(tr[k].lz_add+val)%p;
		tr[k].val=(tr[k].val+val*(r-l+1))%p;
		return;
	}
	push_down(k,l,r);
	int mid=l+r>>1;
	if(x<=mid)modify_add(k<<1,l,mid,x,y,val);
	if(y>=mid+1)modify_add(k<<1|1,mid+1,r,x,y,val);
	push_up(k);
}
int query(int k,int l,int r,int x,int y)
{
	if(x<=l&&y>=r)return tr[k].val%p;
	push_down(k,l,r);
	int mid=l+r>>1;
	int res=0;
	if(x<=mid)res=(res+query(k<<1,l,mid,x,y))%p;
	if(y>=mid+1)res=(res+query(k<<1|1,mid+1,r,x,y))%p;
	return res;
}
void solve()
{
	cin>>n>>m>>p;
	rep(i,1,n)cin>>a[i];
	build(1,1,n);
	while(m--)
	{
		int op;
		cin>>op;
		if(op==1)
		{
			int x,y,k;
			cin>>x>>y>>k;
			modify_mul(1,1,n,x,y,k);
		}
		else if(op==2)
		{
			int x,y,k;
			cin>>x>>y>>k;
			modify_add(1,1,n,x,y,k);
		}
		else if(op==3)
		{
			int x,y;
			cin>>x>>y;
			cout<<query(1,1,n,x,y)<<endl;
		}
	}
}
signed main()
{
    io;
    int _;_=1;
    //cin>>_;
    while(_--)solve();
    return 0;

}

你可能感兴趣的:(算法,数据结构,java)