首页 > 其他分享 >线段树板子

线段树板子

时间:2023-12-24 12:33:26浏览次数:23  
标签:rt cnt int max 线段 tr 板子 static

package ICPC;  
import java.util.*;  
import java.math.*;  
import java.io.*;  
import java.text.DecimalFormat;  
import java.text.NumberFormat;  
class node{
    int l,r,max,cnt;
}
public class Main {  
    static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));  
    static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));  
    static StringTokenizer tokenizer = new StringTokenizer("");  
    static String next() throws IOException {  
        while (!tokenizer.hasMoreTokens()) {  
            tokenizer = new StringTokenizer(reader.readLine());  
        }  
        return tokenizer.nextToken();  
    }  
    static int nextInt() throws IOException {  
        return Integer.parseInt(next());  
    }  
 
    static int N=200010,n,m;
    static node tr[]=new node[4*N];
    static int w[]=new int[N];
    public static void main(String[] args)throws IOException {
        n=nextInt();
        m=nextInt();
        
        for(int i=1;i<=n;i++)w[i]=nextInt();
        
        for(int i=0;i<4*N;i++)tr[i]=new node();
        
        builder(1,1,n);

        while(m-->0) {
            String s=reader.readLine();
            
            String ss[]=s.split(" ");
            int l=Integer.parseInt(ss[1]),r=Integer.parseInt(ss[2]);
            
            if(ss[0].equals("Ask")) {
//                builder(1,1,n);
                int t[]=query(1,l,r);
                pw.println(t[0]+" "+t[1]);
            }else {
                update(1,l,r);
            }
        }
        pw.flush();
    }

    private static void update(int rt, int x, int v) {
        int lc=rt<<1,rc=rt<<1|1;
        
        if(tr[rt].l==x&&tr[rt].r==x) {
            tr[rt].max=v;
            return;
        }
        int mid=(tr[rt].l+tr[rt].r)>>1;
        if(x<=mid)update(lc,x,v);
        if(x>mid)update(rc,x,v);
        pushup(rt);
        
    }

    private static int[] query(int rt, int l, int r) {
        int lc=rt<<1,rc=rt<<1|1;
        if(l<=tr[rt].l&&r>=tr[rt].r) {
            return new int[] {tr[rt].max,tr[rt].cnt};
        }
        
        int mid=(tr[rt].l+tr[rt].r)>>1;
        int sum[]=new int[2];
        if(l<=mid) {
            int t[]=query(lc,l,r);
            if(t[0]>sum[0]) {
                sum[0]=t[0];
                sum[1]=t[1];
            }else if(t[0]==sum[0]) {
                sum[1]+=t[1];
            }
        }
        if(r>mid) {
            int t[]=query(rc,l,r);
            
            if(t[0]>sum[0]) {
                sum[0]=t[0];
                sum[1]=t[1];
            }else if(t[0]==sum[0]) {
                sum[1]+=t[1];
            }
        }
        
        return sum;
    }

    private static void builder(int rt, int l, int r) {
        int lc=rt<<1,rc=rt<<1|1;
        tr[rt].l=l;tr[rt].r=r;tr[rt].max=w[l];tr[rt].cnt=1;
        if(l==r)return;
        int mid=l+r>>1;
        if(l<=mid)builder(lc,l,mid);
        if(r>mid)builder(rc,mid+1,r);
        if(tr[lc].max==tr[rc].max) {
            tr[rt].max=tr[lc].max;
            tr[rt].cnt=tr[lc].cnt+tr[rc].cnt;
        }else if(tr[lc].max>tr[rc].max) {
            tr[rt].max=tr[lc].max;
            tr[rt].cnt=tr[lc].cnt;
        }else {
            tr[rt].max=tr[rc].max;
            tr[rt].cnt=tr[rc].cnt;
        }
    }

    private static void pushup(int rt) {
        
        int lc=rt<<1,rc=rt<<1|1;
        
        if(tr[lc].max==tr[rc].max) {
            tr[rt].max=tr[lc].max;
            tr[rt].cnt=tr[lc].cnt+tr[rc].cnt;
        }else if(tr[lc].max>tr[rc].max) {
            tr[rt].max=tr[lc].max;
            tr[rt].cnt=tr[lc].cnt;
        }else {
            tr[rt].max=tr[rc].max;
            tr[rt].cnt=tr[rc].cnt;
        }
    }
}

 

标签:rt,cnt,int,max,线段,tr,板子,static
From: https://www.cnblogs.com/Lili-202209/p/17924240.html

相关文章

  • 线段树 2
    由于有两个操作,我们要对乘法和加法设置一个优先级我们来看看先乘后加,lazy2表示乘数,lazy1表示加数(前者初始值为\(1\),后者初始值为\(0\))根据我们对lazy的理解,一个节点的和的真实值,为这个节点到根节点的路径中,对每一个节点依次先乘lazy2再加lazy1得到的最终结果假设某一步时,和的中......
  • 多项式板子
    FFT#include<iostream>#include<cstdio>#include<cmath>usingnamespacestd;intlimit,r[10000010];doublepie=acos(-1.0);structcomplex{ doublex,y; complex(doublea=0,doubleb=0){x=a;y=b;}};complexoperator+(complexa,complexb......
  • 线段上离p最近的点 - 投影方式
    点到线段的最近距离判断依据1)投影结果<0,则线段端点a离p最近2)投影结果>线段ab的长度,则线段端点b离p最近3)否则p在线段上的垂点为最近点 p与ab不共线时1)p在线段两侧2-a)p在线段内侧2-b)p在线段内侧2 p与ab共线时1) p在线段两侧 2-a)p在线段内侧2-b......
  • 吉司机线段树
    \(mxb\)为历史最大值,\(tg1,tg2,tg3,tg4\)分别对应最大值真实\(tag\),其他值真实\(tag\),最大值最大\(tag\),其它值最大\(tag\)#include<bits/stdc++.h>usingnamespacestd;#defineN500005#defineintlonglongintn,m;inta[N];structTREE{ intsum[N*4],mxb[N......
  • 线段树与历史最值和区间最值问题
    线段树与历史最值问题P4314CPU监控Description给定数组\(\{a_i\}\),维护以下操作。定义一个辅助数组\(\{b_i\}\),每次操作完后令\(b_i=\max(a_i,b_i)\)。查询\(\max_{i=l}^{r}a_i\)(区间最值)查询\(\max_{i=l}^{r}b_i\)(历史最值)\(\foralli\in[l,r]\),\(a_i\gets......
  • syoj.1827. 线段传送带题解
    前情提要-三分1827.线段传送带P2571[SCOI2010]传送带省流:三分套三分。在二维平面上有两个传送带,一个从A点到B点,一个从C点到D点,速度分别是p和q,在平面内其他点的速度为r。求A点到D点的最小速度。考虑从A到D的路程一定是\(AE+EF+FD\),即通过这两个点连......
  • 线段树详解
    定义什么是线段树线段树是一种二叉搜索树,每个节点都存储了一个区间的问题。能够解决的问题序列维护修改以及查询区间上的最值、求和等,修改和查询的时间复杂度为\(O\)(\(log\)\(n\))。与其他RMQ算法的区别算法适用范围优点缺点线段树动态可执行的操作......
  • 简单线段树
    一、什么是线段树?线段树是怎样的树形结构?线段树是一种二叉搜索树,每个结点都存储了一个区间,也可以理解成一个线段,你要从这些线段上进行搜索操作得到你想要的答案。线段树能够解决什么样的问题?线段树的适用范围很广,可以在线维护修改以及查询区间上的最值,求和。......
  • CF1784C Monsters (hard version) 题解 线段树
    题目链接:https://codeforces.com/problemset/problem/1784/C题目大意:你面前有\(n\)只怪兽,每只怪兽都有一个初始血量,你可以进行两类操作:操作1:选择任意一个血量大于\(0\)的怪兽,并将它的血量降低\(1\);操作2:将所有存活的怪物的血量各自减去\(1\),如果存在怪物的血量恰好降为......
  • 线段树
    线段树什么是线段树线段树(英语:Segmenttree)是一种二叉树形数据结构,1977年由JonLouisBentley发明[1],用以存储区间或线段,并且允许快速查询结构内包含某一点的所有区间。一个包含n个区间的线段树,空间复杂度为O(n),查询的时间复杂度则为O(logn+k)},其中k是匹配条件的区间数量。此......