COJ 0359 xjr考考你数据结构(根号2)线段树区间增加

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

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

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

2)将第addL到addR个数增加v。

 
输入
第一行:n,表示数的个数
第二行:空格分开每个数Ai
第三行:Q,表示操作数目
后Q行:先输入一个字母,
       若字母为“Q”则后面跟上两个数,分别为L与R
       若字母为“A”则后面跟上三个数,分别为addL,addR与v
输出
若干行,按顺序针对每个查询(Q)操作分别输出最大、最小值以及连续和。每行遵守以下格式(行末无空格):
MaxNum: 整数, MinNum: 整数, Sum: 整数
输入示例
5
1 2 3 4 5
3
Q 1 4
A 3 3 2
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];long long mi,mx,sm,add,siz;node(){mi=inf;mx=-inf;sm=add=0;}
 14     void sett(long long tag){mi=mx=sm=tag;return;}
 15     void addt(long long tag){add+=tag;mi+=tag;mx+=tag;sm+=tag*siz;return;}
 16     void down(){if(add){CH{ch[d]->addt(add);}add=0;}return;}
 17     void update(){
 18         mi=inf;mx=-inf;sm=0;
 19         CH{mi=min(mi,ch[d]->mi);mx=max(mx,ch[d]->mx);sm+=ch[d]->sm;}
 20         return;
 21     }
 22 }seg[maxnode],*nodecnt=seg,*root;
 23 int A[maxn],ql,qr,cv;
 24 void build(node*&x,int L,int R){
 25     x=nodecnt++;
 26     if(L==R) x->sett(A[L]);
 27     else{
 28         int M=L+R>>1;
 29         build(x->ch[0],L,M);
 30         build(x->ch[1],M+1,R);
 31         x->update();
 32     } 
 33     x->siz=R-L+1;return;
 34 }
 35 void update(node*&x,int L,int R){
 36     if(ql<=L&&R<=qr) x->addt(cv);
 37     else{
 38         int M=L+R>>1;
 39         x->down();
 40         if(ql<=M) update(x->ch[0],L,M);
 41         if(qr>M) update(x->ch[1],M+1,R);
 42         x->update();
 43     }
 44     return;
 45 }
 46 long long _mi,_mx,_sm;
 47 void query(node*x,int L,int R){
 48     if(ql<=L&&R<=qr){
 49         _mi=min(_mi,x->mi);
 50         _mx=max(_mx,x->mx);
 51         _sm+=x->sm;
 52     }
 53     else{
 54         int M=L+R>>1;
 55         x->down();
 56         if(ql<=M) query(x->ch[0],L,M);
 57         if(qr>M) query(x->ch[1],M+1,R);
 58     } return;
 59 }
 60 inline int read(){
 61     int x=0,sig=1;char ch=getchar();
 62     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
 63     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
 64     return x*=sig;
 65 }
 66 inline void write(int x){
 67     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
 68     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
 69     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
 70 }
 71 inline char readc(){
 72     char ch=getchar();
 73     while(!isalpha(ch)) ch=getchar();
 74     return ch;
 75 }
 76 int n,Q;
 77 void init(){
 78     n=read();
 79     for(int i=1;i<=n;i++) A[i]=read();
 80     build(root,1,n);
 81     return;
 82 }
 83 void work(){
 84     Q=read();char tp;
 85     while(Q--){
 86         tp=readc();ql=read();qr=read();
 87         if(ql>qr) swap(ql,qr);
 88         if(tp=='A'){
 89             cv=read();
 90             update(root,1,n);
 91         }
 92         else{
 93             _mi=inf;_mx=-inf;_sm=0;
 94             query(root,1,n);
 95             printf("MaxNum: %lld, MinNum: %lld, Sum: %lld
",_mx,_mi,_sm);
 96         }
 97     }
 98     return;
 99 }
100 void print(){
101     return;
102 }
103 int main(){init();work();print();return 0;}
原文地址:https://www.cnblogs.com/chxer/p/4393057.html