今天是2017/5/23,DCDCBigBig的第十一篇博文
啊。。。昨天真是太累了。。。把树链剖分先传上来了,用的还是线段树区间修改。然而我并没有传线段树。。。(所以说那份代码是py来的。。。)那这篇博文就多放点模板,给大家发发福利吧^_^
//求区间最值
//n个元素,m个询问
//C x y 代表将第x个元素的值改为y
//D x y 代表在第x到第y个元素中找最大值
//X x y 代表在第x到第y个元素中找最小值
//附带一个print函数,可以遍历并输出叶节点
#include
#include
#include
#include
using namespace std;
struct tree_node{
int maxn,minn;
}t[400001];
int n,m,x,y,a[100001];
char ord[5];
void build(int l,int r,int u){
if(l==r){
t[u].maxn=a[l];
t[u].minn=a[l];
return;
}
int mid=(l+r)/2;
build(l,mid,u*2);
build(mid+1,r,u*2+1);
t[u].maxn=max(t[u*2].maxn,t[u*2+1].maxn);
t[u].minn=min(t[u*2].minn,t[u*2+1].minn);
}
void print(int l,int r,int u){
if(l==r){
printf("%d ",t[u].minn);
return;
}
int mid=(l+r)/2;
print(l,mid,u*2);
print(mid+1,r,u*2+1);
}
void updata(int l,int r,int u,int x,int y){
if(l==r){
t[u].maxn=y;
t[u].minn=y;
return;
}
int mid=(l+r)/2;
if(x<=mid)updata(l,mid,u*2,x,y);
else if(x>mid)updata(mid+1,r,u*2+1,x,y);
t[u].maxn=max(t[u*2].maxn,t[u*2+1].maxn);
t[u].minn=min(t[u*2].minn,t[u*2+1].minn);
}
int query_max(int l,int r,int u,int L,int R){
if(l>=L&&r<=R){
return t[u].maxn;
}
int mid=(l+r)/2,ans=-2147483647;
if(L<=mid)ans=max(ans,query_max(l,mid,u*2,L,R));
if(R>mid)ans=max(ans,query_max(mid+1,r,u*2+1,L,R));
return ans;
}
int query_min(int l,int r,int u,int L,int R){
if(l>=L&&r<=R){
return t[u].minn;
}
int mid=(l+r)/2,ans=2147483647;
if(L<=mid)ans=min(ans,query_min(l,mid,u*2,L,R));
if(R>mid)ans=min(ans,query_min(mid+1,r,u*2+1,L,R));
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
build(1,n,1);
for(int i=1;i<=m;i++){
scanf("%s",ord);
if(ord[0]=='P'){
print(1,n,1);
printf("\n");
continue;
}
scanf("%d%d",&x,&y);
if(ord[0]=='C'){
updata(1,n,1,x,y);
}
if(ord[0]=='D'){
printf("%d\n",query_max(1,n,1,x,y));
}
if(ord[0]=='X'){
printf("%d\n",query_min(1,n,1,x,y));
}
}
return 0;
}
ps:懒癌发作,不知道拖了几天才写好。。。
//区间求和+区间修改(区间加值版)
//类似地,n个元素、m个询问
//Q x y表示询问x至y的和
//A x y z表示将x到y的值全部加上z
#include
#include
#include
#include
using namespace std;
struct tree{
int v,lazy;
}t[400001];
int n,m,x,y,z,a[100001];
char ord[5];
void pd(int u,int l,int r){
if(t[u].lazy!=0){
int mid=(l+r)/2;
t[u*2].lazy+=t[u].lazy;
t[u*2+1].lazy+=t[u].lazy;
t[u*2].v+=t[u].lazy*(mid-l+1);
t[u*2+1].v+=t[u].lazy*(r-mid);
t[u].lazy=0;
}
}
void build(int l,int r,int u){
if(l==r){
t[u].v=a[l];
return;
}
int mid=(l+r)/2;
t[u].lazy=0;
build(l,mid,u*2);
build(mid+1,r,u*2+1);
t[u].v=t[u*2].v+t[u*2+1].v;
}
void updata(int l,int r,int u,int L,int R,int val){
if(L<=l&&r<=R){
t[u].lazy+=val;
t[u].v+=val*(r-l+1);
return;
}
pd(u,l,r);
int mid=(l+r)/2;
if(L<=mid)updata(l,mid,u*2,L,R,val);
if(R>mid)updata(mid+1,r,u*2+1,L,R,val);
t[u].v=t[u*2].v+t[u*2+1].v;
}
int query(int l,int r,int u,int L,int R){
if(L<=l&&r<=R){
return t[u].v;
}
pd(u,l,r);
int mid=(l+r)/2,ans=0;
if(L<=mid)ans+=query(l,mid,u*2,L,R);
if(R>mid)ans+=query(mid+1,r,u*2+1,L,R);
t[u].v=t[u*2].v+t[u*2+1].v;
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
build(1,n,1);
for(int i=1;i<=m;i++){
scanf("%s%d%d",ord,&x,&y);
if(ord[0]=='A'){
scanf("%d",&z);
updata(1,n,1,x,y,z);
}
if(ord[0]=='Q'){
printf("%d\n",query(1,n,1,x,y));
}
}
return 0;
}
/*
5 5
1 2 3 4 5
Q 1 5
A 1 3 5
Q 1 5
A 3 5 -3
Q 1 5
*/
//区间求和+区间修改(区间改值版)
//n个元素、m个询问
//Q x y表示询问x至y的和
//C x y z表示将x到y的值全部改成z
#include
#include
#include
#include
using namespace std;
struct tree{
int v,lazy;
}t[400001];
int n,m,x,y,z,a[100001];
char ord[5];
void pd(int u,int l,int r){
if(t[u].lazy!=0){
int mid=(l+r)/2;
t[u*2].lazy=t[u].lazy;
t[u*2+1].lazy=t[u].lazy;
t[u*2].v=t[u].lazy*(mid-l+1);
t[u*2+1].v=t[u].lazy*(r-mid);
t[u].lazy=0;
}
}
void build(int l,int r,int u){
if(l==r){
t[u].v=a[l];
return;
}
int mid=(l+r)/2;
t[u].lazy=0;
build(l,mid,u*2);
build(mid+1,r,u*2+1);
t[u].v=t[u*2].v+t[u*2+1].v;
}
void updata(int l,int r,int u,int L,int R,int val){
if(L<=l&&r<=R){
t[u].lazy=val;
t[u].v=val*(r-l+1);
return;
}
pd(u,l,r);
int mid=(l+r)/2;
if(L<=mid)updata(l,mid,u*2,L,R,val);
if(R>mid)updata(mid+1,r,u*2+1,L,R,val);
t[u].v=t[u*2].v+t[u*2+1].v;
}
int query(int l,int r,int u,int L,int R){
if(L<=l&&r<=R){
return t[u].v;
}
pd(u,l,r);
int mid=(l+r)/2,ans=0;
if(L<=mid)ans+=query(l,mid,u*2,L,R);
if(R>mid)ans+=query(mid+1,r,u*2+1,L,R);
t[u].v=t[u*2].v+t[u*2+1].v;
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
build(1,n,1);
for(int i=1;i<=m;i++){
scanf("%s%d%d",ord,&x,&y);
if(ord[0]=='C'){
scanf("%d",&z);
updata(1,n,1,x,y,z);
}
if(ord[0]=='Q'){
printf("%d\n",query(1,n,1,x,y));
}
}
return 0;
}
/*
5 5
1 2 3 4 5
Q 1 5
C 1 3 5
Q 1 5
C 3 5 -3
Q 1 5
*/
//单点修改可持久化线段树(非主席树)
//给出n个数,q个询问
//每次询问形如 0 k l r 或 1 k i x
//表示询问第k个版本l到r之间的最大值或把第k个版本的第i个数改为x
//初始的n个数表示第一个版本
#include
#include
#include
#include
using namespace std;
struct node{
int mx,ls,rs;
}t[2000001];
int n,q,k,l,r,ord,cnt=0,tot=0,rt[100001],num[100001];
void build(int l,int r,int &u){
if(!u)u=++tot;
if(l==r){
t[u].mx=num[l];
return;
}
int mid=(l+r)/2;
build(l,mid,t[u].ls);
build(mid+1,r,t[u].rs);
t[u].mx=max(t[t[u].ls].mx,t[t[u].rs].mx);
}
void ins(int &k,int last,int l,int r,int p,int x){
t[k=++tot].mx=t[last].mx;
if(l==r){
t[k].mx=x;
return;
}
t[k].ls=t[last].ls;
t[k].rs=t[last].rs;
int mid=(l+r)/2;
if(p<=mid)ins(t[k].ls,t[last].ls,l,mid,p,x);
else ins(t[k].rs,t[last].rs,mid+1,r,p,x);
t[k].mx=max(t[t[k].ls].mx,t[t[k].rs].mx);
}
int query(int &k,int l,int r,int L,int R){
if(!k)return 0;
if(L==l&&r==R){
return t[k].mx;
}
int mid=(l+r)/2;
if(R<=mid)return query(t[k].ls,l,mid,L,R);
else if(L>mid)return query(t[k].rs,mid+1,r,L,R);
else return max(query(t[k].ls,l,mid,L,mid),query(t[k].rs,mid+1,r,mid+1,R));
}
int main(){
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++){
scanf("%d",&num[i]);
}
build(1,n,rt[++cnt]);
for(int i=1;i<=q;i++){
scanf("%d%d%d%d",&ord,&k,&l,&r);
if(ord==1){
ins(rt[++cnt],rt[k],1,n,l,r);
}else{
printf("%d\n",query(rt[k],1,n,l,r));
}
}
return 0;
}
//hdu4348
//标记永久化是真的省空间!!!
#include
#include
#include
#include
using namespace std;
typedef long long ll;
struct node{
int ls,rs;
ll v,lazy;
}t[5000001];
int n,m,k,l,r,v,tot,cnt,num[100001],rt[100001];
char ord[3];
int build(int l,int r){
int u=++tot;
t[u].lazy=0;
if(l==r){
t[u].v=num[l];
return u;
}
int mid=(l+r)/2;
t[u].ls=build(l,mid);
t[u].rs=build(mid+1,r);
t[u].v=t[t[u].ls].v+t[t[u].rs].v;
return u;
}
int rebuild(int l,int r,int L,int R,int v,int k){
int u=++tot;
t[u].v=t[k].v;
t[u].ls=t[k].ls;
t[u].rs=t[k].rs;
t[u].lazy=t[k].lazy;
if(l==L&&r==R){
t[u].lazy+=v;
t[u].v+=v*(r-l+1);
return u;
}
int mid=(l+r)/2;
if(R<=mid)t[u].ls=rebuild(l,mid,L,R,v,t[k].ls);
else if(L>mid)t[u].rs=rebuild(mid+1,r,L,R,v,t[k].rs);
else{
t[u].ls=rebuild(l,mid,L,mid,v,t[k].ls);
t[u].rs=rebuild(mid+1,r,mid+1,R,v,t[k].rs);
}
t[u].v=t[t[u].ls].v+t[t[u].rs].v;
t[u].v+=t[u].lazy*(r-l+1);
return u;
}
ll query(int l,int r,int u,int L,int R){
if(l==L&&r==R){
return t[u].v;
}
int mid=(l+r)/2;
ll ans=0;
if(L>=l&&R<=r)ans+=t[u].lazy*(R-L+1);
else if(L=l&&R<=r)ans+=t[u].lazy*(R-l+1);
else if(R>r&&L>=l&&L<=r)ans+=t[u].lazy*(r-L+1);
else if(Lr)ans+=t[u].lazy*(r-l+1);
if(R<=mid)ans+=query(l,mid,t[u].ls,L,R);
else if(L>mid)ans+=query(mid+1,r,t[u].rs,L,R);
else ans+=query(l,mid,t[u].ls,L,mid)+query(mid+1,r,t[u].rs,mid+1,R);
return ans;
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
tot=cnt=0;
for(int i=1;i<=n;i++){
scanf("%d",&num[i]);
}
rt[0]=build(1,n);
for(int i=1;i<=m;i++){
scanf("%s",ord);
if(ord[0]=='C'){
scanf("%d%d%d",&l,&r,&v);
rt[cnt+1]=rebuild(1,n,l,r,v,rt[cnt]);
cnt++;
}else if(ord[0]=='Q'){
scanf("%d%d",&l,&r);
printf("%lld\n",query(1,n,rt[cnt],l,r));
}else if(ord[0]=='H'){
scanf("%d%d%d",&l,&r,&v);
printf("%lld\n",query(1,n,rt[v],l,r));
}else{
scanf("%d",&v);
cnt=v;
}
}
}
return 0;
}
//Orz hjt
//其实和可持久化线段是还是有点区别的QAQ
#include
#include
#include
#include
#include
using namespace std;
struct node{
int ls,rs,v;
}t[2000001];
int n,q,k,l,r,pos,tot=0,cnt=0,a[100001],b[100001],rt[100001];
int build(int l,int r){
int u=++tot;
t[u].v=0;
if(l==r)return u;
int mid=(l+r)/2;
t[u].ls=build(l,mid);
t[u].rs=build(mid+1,r);
return u;
}
int ins(int l,int r,int k,int p){
int u=++tot;
t[u].ls=t[k].ls;
t[u].rs=t[k].rs;
t[u].v=t[k].v+1;
if(l==r)return u;
int mid=(l+r)/2;
if(p<=mid)t[u].ls=ins(l,mid,t[k].ls,p);
else t[u].rs=ins(mid+1,r,t[k].rs,p);
return u;
}
int query(int l,int r,int pre,int now,int k){
if(t[now].ls==t[now].rs){
return b[l];
}
int mid=(l+r)/2,tmp=t[t[now].ls].v-t[t[pre].ls].v;
if(tmp>=k)return query(l,mid,t[pre].ls,t[now].ls,k);
else return query(mid+1,r,t[pre].rs,t[now].rs,k-tmp);
}
int main(){
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+n+1);
rt[0]=build(1,n);
//printf("a\n");
for(int i=1;i<=n;i++)rt[i]=ins(1,n,rt[i-1],lower_bound(b+1,b+n+1,a[i])-b);
for(int i=1;i<=q;i++){
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",query(1,n,rt[l-1],rt[r],k));
}
return 0;
}