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(‘\n‘)
  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\n",_mx,_mi,_sm);
 97         }
 98     }
 99     return;
100 }
101 void print(){
102     return;
103 }
104 int main(){init();work();print();return 0;}
时间: 2024-12-21 20:59:18

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

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”则后面跟上三个数,分别为a

COJ 1010 WZJ的数据结构(十) 线段树区间操作

传送门:http://oj.cnuschool.org.cn/oj/home/problem.htm?problemID=1001 WZJ的数据结构(十) 难度级别:D: 运行时间限制:3000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 请你设计一个数据结构,高效执行以下过程: #include<iostream>using namespace std;const int maxn=100010;int A[maxn];int tp,ql,qr,v;int

hdu 4027 Can you answer these queries? 线段树区间开根号,区间求和

Can you answer these queries? Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5195 Description A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our secret weapo

白话数据结构之【线段树】

线段树的入门 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b].因此线段树是平衡二叉树,最后的子节点数目为N,即整个线段区间的长度. 使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logN).而未优化的空间复杂度为2N,因此有时需要离散化让空间压缩. ----来自百度百科 [

《数据结构》线段树入门(二)

今天继续介绍——线段树之延迟标记 接上期<数据结构>线段树入门(一):http://www.cnblogs.com/shadowland/p/5870339.html 在上期介绍了线段树的最基本内容(线段树单点修改,区间查询),这次将介绍:区间修改,区间查询. Question: 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述: 第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,每行表示操作的个数,如果第一数是1,后接3个正

刷题向》关于线段树的区间开根号 BZOJ3211

这是一道关于线段树的区间开根号的裸题,没什么好讲的. 值得注意的是,因为有区间开根号的性质,所以我们每一次更改操作只能把更改区间所覆盖的所有元素全部查找,当然你直接找效率明显爆炸... 能够注意到,指数级别的操作一次更改的数字都很大,而题目的数字最大是10的9次,所以可以注意到的是当一个区间更新6遍以后就失去更新的意义了,因为当你更改次数超过6次所有非负整数数字就全部会化为1.所以可以在每一个节点上加一个类似于LAZY标记的东西,记录开根号次数,以便节约跟新时间. 贴出题目&代码 Descrip

线段树--数据结构专题学习

这两周是数据结构专题的学习,,被专题的题目虐得死去活来== 线段树:简单的说就是把[1,n]的区间二分,[1,(1+n)/2]左子树,[(1+n)/2+1,n]右子树 就这样一直分下去,直到都是[x,x]这样的区间.这样就构成了一颗树了^-^ 有这样一棵树,我们就可以在节点中储存区间的和啊,区间内的最大值啊,最小值等等..这就是线段树的附加信息了,也是题目中的重点.. 我们可以用一个数组(长度为k)储存原区间的初始值,然后根据这个建树,所以这个树的节点数最多为4*K: 对于每个节点i,其左子树为

高级数据结构实现——自顶向下伸展树

[0]README 1) 本文部分内容转自 数据结构与算法分析,旨在理解 高级数据结构实现——自顶向下伸展树 的基础知识: 2) 源代码部分思想借鉴了数据结构与算法分析,有一点干货原创代码,for original source code, please visithttps://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter12/p345_topdown_splay_tree 3) you c

数据结构--M - 秋实大哥与线段树(单点更新与区间查询)

M - 秋实大哥与线段树 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status “学习本无底,前进莫徬徨.” 秋实大哥对一旁玩手机的学弟说道. 秋实大哥是一个爱学习的人,今天他刚刚学习了线段树这个数据结构. 为了检验自己的掌握程度,秋实大哥给自己出了一个题,同时邀请大家一起来作. 秋实大哥的题目要求你维护一个序列,支持两种操作:一种是修改某一个元素的值:一