开始试想直接用容器来暴力做,,,,,,
恩。。。。。线段树。。。。
记不得以前写没写过了,,,,
先来个模板先(就是那种n个询问成段更新的题)
#include<stdio.h>
#include<string.h>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define root 1 , N , 1
#define LL long long
const int maxn = 111111;
LL add[maxn<<2];
LL sum[maxn<<2];
void PushUp(int rt) {
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void PushDown(int rt,int m) {
if (add[rt])
{
add[rt<<1] += add[rt];
add[rt<<1|1] += add[rt];
sum[rt<<1] += add[rt] * (m - (m >> 1));
sum[rt<<1|1] += add[rt] * (m >> 1);
add[rt] = 0;
}
}
void build(int l,int r,int rt)
{
add[rt] = 0;
if (l == r) {
scanf("%lld",&sum[rt]);
return ;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
PushUp(rt);
}
void update(int L,int R,int c,int l,int r,int rt) {
if (L <= l && r <= R) {
add[rt] += c;
sum[rt] += (LL)c * (r - l + 1);
return ;
}
PushDown(rt , r - l + 1);
int m = (l + r) >> 1;
if (L <= m) update(L , R , c , lson);
if (m < R) update(L , R , c , rson);
PushUp(rt);
}
LL query(int L,int R,int l,int r,int rt) {
if (L <= l && r <= R) {
return sum[rt];
}
PushDown(rt , r - l + 1);
int m = (l + r) >> 1;
LL ret = 0;
if (L <= m) ret += query(L , R , lson);
if (m < R) ret += query(L , R , rson);
return ret;
}
int main() {
int N , Q;
scanf("%d%d",&N,&Q);
build(root);
while (Q --) {
char op[2];
int a , b , c;
scanf("%s",op);
if (op[0] == ‘Q‘) {
scanf("%d%d",&a,&b);
printf("%lld\n",query(a , b ,root));
} else {
scanf("%d%d%d",&a,&b,&c);
update(a , b , c , root);
}
}
return 0;
}
/*我们开26棵线段树,第i棵线段树维护的是:26个字母中排第i个的字母在各个区间的数目。*/
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int aint[400005][27], lazy[400005], i, x, y, op, n, q, aux[27], paux;
string s;
void init(int nod, int l, int r) {
if (l==r) aint[nod][int(s[l-1]-‘a‘)]=1;
else {
int mid=(l+r)/2;
init(2*nod,l,mid);
init(2*nod+1,mid+1,r);
for (int i=0; i<26; ++i) aint[nod][i]=aint[2*nod][i]+aint[2*nod+1][i];
}
}
void buildsol(int nod, int l, int r) {
if (lazy[nod]==1) {//update crescator pe fii
int p=0, nr=aint[nod][0];
int mid=(l+r)/2;
int leftlen=mid-l+1;
memset(aint[2*nod],0,sizeof(aint[2*nod]));
memset(aint[2*nod+1],0,sizeof(aint[2*nod+1]));
while (nr<=leftlen) {
aint[2*nod][p]=aint[nod][p];
++p;
nr+=aint[nod][p];
}
nr-=aint[nod][p];
if (nr<leftlen) aint[2*nod][p]=leftlen-nr;
if (leftlen>1) lazy[2*nod]=1;
aint[2*nod+1][p]=aint[nod][p]-(leftlen-nr);
++p;
while (p<26) {
aint[2*nod+1][p]=aint[nod][p];
++p;
}
if (r-mid>1) lazy[2*nod+1]=1;
lazy[nod]=0;
}
else if (lazy[nod]==2) {//update descrescator pe fii
int p=25, nr=aint[nod][25];
int mid=(l+r)/2;
int leftlen=mid-l+1;
memset(aint[2*nod],0,sizeof(aint[2*nod]));
memset(aint[2*nod+1],0,sizeof(aint[2*nod+1]));
while (nr<=leftlen) {
aint[2*nod][p]=aint[nod][p];
--p;
nr+=aint[nod][p];
}
nr-=aint[nod][p];
if (nr<leftlen) aint[2*nod][p]=leftlen-nr;
if (leftlen>1) lazy[2*nod]=2;
aint[2*nod+1][p]=aint[nod][p]-(leftlen-nr);
--p;
while (p>=0) {
aint[2*nod+1][p]=aint[nod][p];
--p;
}
if (r-mid>1) lazy[2*nod+1]=2;
lazy[nod]=0;
}
if (l==r) {
int k=0;
while (aint[nod][k]==0) ++k;
s+=char(k+‘a‘);
}
else {
int mid=(l+r)/2;
buildsol(2*nod,l,mid);
buildsol(2*nod+1,mid+1,r);
}
}
void getnumbers(int nod, int l, int r, int x, int y) {
if (lazy[nod]==1) {//update crescator pe fii
int p=0, nr=aint[nod][0];
int mid=(l+r)/2;
int leftlen=mid-l+1;
memset(aint[2*nod],0,sizeof(aint[2*nod]));
memset(aint[2*nod+1],0,sizeof(aint[2*nod+1]));
while (nr<=leftlen) {
aint[2*nod][p]=aint[nod][p];
++p;
nr+=aint[nod][p];
}
nr-=aint[nod][p];
if (nr<leftlen) aint[2*nod][p]=leftlen-nr;
if (leftlen>1) lazy[2*nod]=1;
aint[2*nod+1][p]=aint[nod][p]-(leftlen-nr);
++p;
while (p<26) {
aint[2*nod+1][p]=aint[nod][p];
++p;
}
if (r-mid>1) lazy[2*nod+1]=1;
lazy[nod]=0;
}
else if (lazy[nod]==2) {//update descrescator pe fii
int p=25, nr=aint[nod][25];
int mid=(l+r)/2;
int leftlen=mid-l+1;
memset(aint[2*nod],0,sizeof(aint[2*nod]));
memset(aint[2*nod+1],0,sizeof(aint[2*nod+1]));
while (nr<=leftlen) {
aint[2*nod][p]=aint[nod][p];
--p;
nr+=aint[nod][p];
}
nr-=aint[nod][p];
if (nr<leftlen) aint[2*nod][p]=leftlen-nr;
if (leftlen>1) lazy[2*nod]=2;
aint[2*nod+1][p]=aint[nod][p]-(leftlen-nr);
--p;
while (p>=0) {
aint[2*nod+1][p]=aint[nod][p];
--p;
}
if (r-mid>1) lazy[2*nod+1]=2;
lazy[nod]=0;
}
if (l>=x&&r<=y) {
for (int i=0; i<=25; ++i) aux[i]+=aint[nod][i];
}
else {
int mid=(l+r)/2;
if (x<=mid) getnumbers(2*nod,l,mid,x,y);
if (y>mid) getnumbers(2*nod+1,mid+1,r,x,y);
}
}
void updatecresc(int nod, int l, int r,int x, int y) {
if (l>=x&&r<=y) {
for (int i=0; i<26; ++i) aint[nod][i]=0;
int nr=aux[paux];
int len=(r-l+1);
while (nr<=len&&paux<=25) {
aint[nod][paux]=aux[paux];
++paux;
nr+=aux[paux];
}
if (paux<=25) {
nr-=aux[paux];
if (nr<len) aint[nod][paux]=len-nr;
aux[paux]-=(len-nr);
if (aux[paux]==0) ++paux;
}
if (l<r) lazy[nod]=1;
}
else {
int mid=(l+r)/2;
if (x<=mid) updatecresc(2*nod,l,mid,x,y);
if (y>mid) updatecresc(2*nod+1,mid+1,r,x,y);
for (int i=0; i<26; ++i) aint[nod][i]=aint[2*nod+1][i]+aint[2*nod][i];
}
}
void updatedesc(int nod, int l, int r, int x, int y) {
if (l>=x&&r<=y) {
for (int i=0; i<26; ++i) aint[nod][i]=0;
int nr=aux[paux];
int len=(r-l+1);
while (nr<=len&&paux>=0) {
aint[nod][paux]=aux[paux];
--paux;
if (paux>=0) nr+=aux[paux];
}
if (paux>=0) {
nr-=aux[paux];
if (nr<len) aint[nod][paux]=len-nr;
aux[paux]-=(len-nr);
if (aux[paux]==0) --paux;
}
if (l<r) lazy[nod]=2;
}
else {
int mid=(l+r)/2;
if (x<=mid) updatedesc(2*nod,l,mid,x,y);
if (y>mid) updatedesc(2*nod+1,mid+1,r,x,y);
for (int i=0; i<26; ++i) aint[nod][i]=aint[2*nod+1][i]+aint[2*nod][i];
}
}
void sortcresc(int x, int y) {
memset(aux,0,sizeof(aux));
getnumbers(1,1,n,x,y);
paux=0;
updatecresc(1,1,n,x,y);
}
void sortdesc(int x, int y) {
memset(aux,0,sizeof(aux));
getnumbers(1,1,n,x,y);
paux=25;
updatedesc(1,1,n,x,y);
}
int main(void) {
cin>>n>>q;
getline(cin,s);
getline(cin,s);
init(1,1,n);
for (; q; --q) {
cin>>x>>y>>op;
if (op==1) sortcresc(x,y);
else sortdesc(x,y);
}
s="";
buildsol(1,1,n);
cout<<s;
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。