COJ 0358 xjr考考你数据结构(根号3)线段树区间修改

xjr考考你数据结构(根号3)
难度级别:C; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B
试题描述

请你编写一个数据结构,完成以下功能:

1)求出第L个到第R个数中的最大、最小值以及连续和。

2)将第addL到addR个数改成v。

 
输入
第一行:n,表示数的个数
第二行:空格分开每个数Ai
第三行:Q,表示操作数目
后Q行:先输入一个字母,
       若字母为“Q”则后面跟上两个数,分别为L与R
       若字母为“C”则后面跟上三个数,分别为addL,addR与v
输出
若干行,按顺序针对每个查询(Q)操作分别输出最大、最小值以及连续和。每行遵守以下格式(行末无空格):
MaxNum: 整数, MinNum: 整数, Sum: 整数
输入示例
5
1 2 3 4 5
3
Q 1 4
C 3 3 5
Q 1 5
输出示例
MaxNum: 4, MinNum: 1, Sum: 10
MaxNum: 5, MinNum: 1, Sum: 17
其他说明
0 < n, q < 100001
0 < Ai < 2001
0 < L, R < n + 1

题解:线段树大水题

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<queue>
  6 #include<cstring>
  7 #define PAU putchar(' ')
  8 #define ENT putchar('
')
  9 #define CH for(int d=0;d<=1;d++) if(ch[d])
 10 using namespace std;
 11 const int maxn=100000+10,maxnode=200000+10,inf=-1u>>1;
 12 struct node{
 13     node*ch[2];int mi,mx,sm,add,set,siz;node(){mi=inf;mx=-inf;sm=0;set=inf;}
 14     void sett(int tag){mi=mx=set=tag;sm=tag*siz;return;}
 15     void down(){
 16         if(set!=inf){CH{ch[d]->sett(set);}set=inf;}
 17         return;
 18     }
 19     void update(){
 20         mi=inf;mx=-inf;sm=0;
 21         CH{mi=min(mi,ch[d]->mi);mx=max(mx,ch[d]->mx);sm+=ch[d]->sm;}
 22         return;
 23     }
 24 }seg[maxnode],*nodecnt=seg,*root;
 25 int A[maxn],ql,qr,cv,tp;
 26 void build(node*&x,int L,int R){
 27     x=nodecnt++;
 28     if(L==R) x->mi=x->mx=x->sm=A[L];
 29     else{
 30         int M=L+R>>1;
 31         build(x->ch[0],L,M);
 32         build(x->ch[1],M+1,R);
 33         x->update();
 34     } x->siz=R-L+1;return;
 35 }
 36 void update(node*&x,int L,int R){
 37     if(ql<=L&&R<=qr) x->sett(cv);
 38     else{
 39         int M=L+R>>1;
 40         x->down();
 41         if(ql<=M) update(x->ch[0],L,M);
 42         if(qr>M) update(x->ch[1],M+1,R);
 43         x->update();
 44     }
 45     return;
 46 }
 47 int _mi,_mx,_sm;
 48 void query(node*x,int L,int R){
 49     if(ql<=L&&R<=qr){
 50         _mi=min(_mi,x->mi);
 51         _mx=max(_mx,x->mx);
 52         _sm+=x->sm;
 53     }
 54     else{
 55         int M=L+R>>1;
 56         x->down();
 57         if(ql<=M) query(x->ch[0],L,M);
 58         if(qr>M) query(x->ch[1],M+1,R);
 59     } return;
 60 }
 61 inline int read(){
 62     int x=0,sig=1;char ch=getchar();
 63     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
 64     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
 65     return x*sig;
 66 }
 67 inline void write(int x){
 68     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
 69     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
 70     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
 71 }
 72 inline char readc(){
 73     char x=getchar();
 74     while(!isalpha(x)) x=getchar();
 75     return x;
 76 }
 77 int n,Q;
 78 void init(){
 79     n=read();
 80     for(int i=1;i<=n;i++) A[i]=read();
 81     build(root,1,n);
 82     return;
 83 }
 84 void work(){
 85     Q=read();char ch;
 86     while(Q--){
 87         ch=readc();ql=read();qr=read();
 88         if(ql>qr) swap(ql,qr);
 89         if(ch=='C'){
 90             cv=read();
 91             update(root,1,n);
 92         }
 93         else{
 94             _mi=inf;_mx=-inf;_sm=0;
 95             query(root,1,n);
 96             printf("MaxNum: %d, MinNum: %d, Sum: %d
",_mx,_mi,_sm);
 97         }
 98     }
 99     return;
100 }
101 void print(){
102     return;
103 }
104 int main(){init();work();print();return 0;}
原文地址:https://www.cnblogs.com/chxer/p/4572445.html