BIT
int tr[maxn];
void add(int x, int t)
{
for(int i=x; i<=n; i+=(i&(-i))) (tr[i]+=t)%=mod;
}
int get(int x)
{
int ret=0;
for(int i=x; i; i-=(i&(-i))) (ret+=tr[i])%=mod;
return ret;
}
Segment_tree
struct segment_tree
{
int x,y,z,w;
}tr[maxn*4];
void pushup(int k)
{
tr[k].z=max(tr[lson].z,tr[rson].z);
}
void pushdown(int k)
{
int w=tr[k].w;
tr[lson].w+=w;
tr[lson].z+=w;
tr[rson].w+=w;
tr[rson].z+=w;
tr[k].w=0;
}
void build(int k,int l,int r)
{
tr[k].w=0,tr[k].x=l,tr[k].y=r;
if (l==r)
{
tr[k].z=c[l];
return;
}
int mid=(l+r)/2;
build(lson,l,mid);
build(rson,mid+1,r);
pushup(k);
}
void update(int k,int l,int r,int w)
{
if (tr[k].y<l||tr[k].x>r) return;
if (l<=tr[k].x&&tr[k].y<=r)
{
tr[k].w+=w;
tr[k].z+=w;
return;
}
if (tr[k].w) pushdown(k);
update(lson,l,r,w);
update(rson,l,r,w);
pushup(k);
}
int query(int k,int l,int r)
{
if (tr[k].y<l||tr[k].x>r) return 0;
if (l<=tr[k].x&&tr[k].y<=r)
{
return tr[k].z;
}
if (tr[k].w) pushdown(k);
return max(query(lson,l,r),query(rson,l,r));
}
一。线段树的operator + 直接合并的写法
二。树状数组加离散化
线段树(区间加区间统计)
#include<bits/stdc++.h>
#define FOR(i,x,y) for (int (i)=(x);(i)<=(y);(i)++)
#define PER(i,y,x) for (int (i)=(y);(i)>=(x);(i)--)
#define LL long long
#define lson k*2
#define rson k*2+1
#define mid ((l+r)>>1)
using namespace std;
const int maxn=200000+10;
struct tree
{
int l,r,ll,rr,sz;
LL tot;
} t[maxn*4];
int a[maxn];
tree operator + (tree a,tree b)
{
tree c;
c.l=a.l;
c.r=b.r;
c.sz=a.sz+b.sz;
c.ll=(a.r<=b.l&&a.ll==a.sz)?(a.ll+b.ll):a.ll;
c.rr=(a.r<=b.l&&b.rr==b.sz)?(a.rr+b.rr):b.rr;
c.tot=a.tot+b.tot+((a.r<=b.l)?1ll*a.rr*b.ll:0ll);
return c;
}
void build(int k,int l,int r)
{
if (l==r)
{
t[k]=(tree){a[l],a[l],1,1,1,1ll};
return;
}
build(lson,l,mid);
build(rson,mid+1,r);
t[k]=t[lson]+t[rson];
}
void update(int k,int l,int r,int x,int y)
{
if (l==r)
{
t[k].l=y;
t[k].r=y;
return;
}
if (x<=mid) update(lson,l,mid,x,y);
else if (x>mid) update(rson,mid+1,r,x,y);
t[k]=t[lson]+t[rson];
}
tree query(int k,int l,int r,int ql,int qr)
{
if (ql==l&&qr==r)
{
return t[k];
}
if (qr<=mid)
{
return query(lson,l,mid,ql,qr);
}
else if (ql>mid)
{
return query(rson,mid+1,r,ql,qr);
}
else return query(lson,l,mid,ql,mid)+query(rson,mid+1,r,mid+1,qr);
}
using namespace std;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
FOR(i,1,n)
{
scanf("%d",&a[i]);
}
build(1,1,n);
FOR(i,1,m)
{
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
if (op==1)
{
update(1,1,n,x,y);
}
else
{
tree tmp=query(1,1,n,x,y);
LL ans=tmp.tot;
printf("%lld
",ans);
}
}
}
树状数组加离散化
//https://ac.nowcoder.com/acm/contest/3566/C
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=5e5+10;
const int mod=998244353;
int d[maxn];
int c[maxn];
int p[maxn];
int tot;
struct tree
{
ll tr[maxn];
void add(int x, ll t)
{
for(int i=x; i<=tot; i+=(i&(-i))) (tr[i]+=t)%=mod;
}
ll get_sum(int x)
{
ll ret=0;
for(int i=x; i; i-=(i&(-i))) (ret+=tr[i])%=mod;
return ret;
}
}T[11];
int main()
{
int n,m;
cin>>n>>m;
for (int i=1;i<=n;i++)
{
scanf("%d",&d[i]);//original array
c[++tot]=d[i]; //ordered array
}
c[++tot]=0;
sort(c+1,c+1+tot);
tot=unique(c+1,c+1+tot)-c-1;
for (int i=1;i<=n;i++)
{
p[i]=lower_bound(c+1,c+1+tot,d[i])-c;//corresponding id.
}
T[0].add(1,1);//little trick
for (int i=1;i<=n;i++)
{
int pos=p[i];
for (int lay=1;lay<=m;lay++)
{
ll num=T[lay-1].get_sum(pos-1);
T[lay].add(pos,num);
}
}
ll ans=T[m].get_sum(tot);
cout<<ans<<endl;
}