HFUUOJ1024 动态开点线段树+标记永久化

题意

分析

动态加点线段树,标记永久化好写常数小

Code

#include<bits/stdc++.h>
#define fi first
#define se second
#define lson l,mid,p<<1
#define rson mid+1,r,p<<1|1
#define pb push_back
#define ll long long
using namespace std;
const ll inf=1e18;
const int mod=1e9+7;
const int maxn=1e7+10;
int n,m;
ll tr[maxn];
int ls[maxn],rs[maxn],tag[maxn],tot;
int rt;
void up(ll x,ll y,ll l,ll r,int &p,ll k){
    tr[++tot]=(tr[p]+(y-x+1)%mod*k%mod)%mod;
    ls[tot]=ls[p],rs[tot]=rs[p],tag[tot]=tag[p],p=tot;
    if(x==l&&y==r){
        tag[p]=(tag[p]+k)%mod;
        return;
    }ll mid=l+r>>1;
    if(y<=mid) up(x,y,l,mid,ls[p],k);
    else if(x>mid) up(x,y,mid+1,r,rs[p],k);
    else up(x,mid,l,mid,ls[p],k),up(mid+1,y,mid+1,r,rs[p],k);
}
ll qy(ll x,ll y,ll l,ll r,int p,ll k){
    if(x==l&&y==r){
        return (tr[p]+(y-x+1)%mod*k%mod)%mod;
    }ll mid=l+r>>1;
    if(y<=mid) return qy(x,y,l,mid,ls[p],(k+tag[p])%mod);
    else if(x>mid) return qy(x,y,mid+1,r,rs[p],(k+tag[p])%mod);
    else return (qy(x,mid,l,mid,ls[p],(k+tag[p])%mod)+qy(mid+1,y,mid+1,r,rs[p],(k+tag[p])%mod))%mod;
}
int main(){
    //ios::sync_with_stdio(false);
    //freopen("in","r",stdin);
    cin>>m;
    for(int i=1,op;i<=m;i++){
        ll x,l,r;scanf("%d%lld%lld",&op,&l,&r);
        if(op==1){
            scanf("%lld",&x);
            x%=mod;
            up(l,r,1,inf,rt,x);
        }else{
            printf("%lld\n",qy(l,r,1,inf,rt,0));
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/xyq0220/p/11509716.html

时间: 2024-10-07 03:48:54

HFUUOJ1024 动态开点线段树+标记永久化的相关文章

【BZOJ-4636】蒟蒻的数列 动态开点线段树 ||(离散化) + 标记永久化

4636: 蒟蒻的数列 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 247  Solved: 113[Submit][Status][Discuss] Description 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个数列,初始值均为0,他进行N次操作,每次将数列[a,b)这个区间中所有比k小的数改为k,他想知 道N次操作后数列中所有元素的和.他还要玩其他游戏,所以这个问题留给你解决. Input 第一

Codeforces 803G Periodic RMQ Problem ST表+动态开节点线段树

思路: (我也不知道这是不是正解) ST表预处理出来原数列的两点之间的min 再搞一个动态开节点线段树 节点记录ans 和标记 lazy=-1 当前节点的ans可用  lazy=0 没被覆盖过 else 区间覆盖 push_up的时候要注意好多细节,, 数组尽量往大开 //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const in

POJ 2155 Matrix 二维线段树+标记永久化?

题意:链接 方法:二维线段树+标记永久化 解析:题意是比较明朗的,算一下内存发现4000^2也是可以接受的,于是就开始yy二维线段树? 对于第一层x的线段树,每个节点开一整棵y线段树. 用个二维数组就实现了? 不过发现个问题啊,这题怎么pushdown啊,标记传不下去啊.如果给x打个标记那么怎么知道y传那段啊? 于是就学了新的东西?标记永久化. 本题是单点查询嘛,标记永久化就应该是把相应的区间直接异或,不用往下传?那查询的时候怎么办呢?只需要在查询的时候把所有路过该点的区间都异或起来就OK了.貌

CF915E Physical Education Lessons|动态开点线段树

动态开点线段树 题目暗示了区间修改,所以我们自然想到了用线段树来维护非工作日的天数. 然而我们再看一下数据范围,天数n的范围是\(1 \le n \le 10^9\),像普通线段树一样预处理显然会爆空间. 天无绝人之路,我们看一下修改个数,$1\le q \le 3 \cdot 10^5 $, 比天数少很多,这也意味着,我们预先处理好的线段树有些节点并没有用 能否优化呢?答案是肯定的,这就是动态开点线段树,顾名思义,我们只要到用某个节点的时候,才分配一个点给它,这样使得我们使用的空间大大减少.其

HDU 6183 Color it(动态开点线段树)

题目原网址:http://acm.hdu.edu.cn/showproblem.php?pid=6183 题目中文翻译: Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 1677    Accepted Submission(s): 500 Problem Description 你喜欢画画吗? Little D不喜欢画画,特别

【bzoj3939】[Usaco2015 Feb]Cow Hopscotch 动态开点线段树优化dp

题目描述 Just like humans enjoy playing the game of Hopscotch, Farmer John's cows have invented a variant of the game for themselves to play. Being played by clumsy animals weighing nearly a ton, Cow Hopscotch almost always ends in disaster, but this has

【bzoj4999】This Problem Is Too Simple! 树链剖分+动态开点线段树

题目描述 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x. 2. Q i j x(0<=x<2^31) 表示询问i节点到j节点的路径上有多少个值为x的节点. 输入 第一行有两个整数N,Q(1 ≤N≤ 100,000:1 ≤Q≤ 200,000),分别表示节点个数和操作个数. 下面一行N个整数,表示初始时每个节点的初始值. 接下来N-1行,每行两个整数x,y,表示x节点与y节点之间有边直接相连(描述一颗树).

[知识点]线段树标记永久化

前言: 本文由Hallmeow原创,转载请注明出处! 由于打丧心病狂的 [BZOJ 4826]影魔  导致需要学习标记永久化,于是入坑OvO 知识点:线段树标记永久化 对于树套树,主席树等使用到线段树的比较复杂的数据结构,如果我们区间修改的话,打标记后pushdown或者pushup是很费劲的 那么我们能不能不用pushdown和pushup呢?当然可以啦!这样就用到标记永久化了! 原理就是: 在路过该节点的时候把修改对答案的影响加上,来省去标记下放的过程 实现起来: 线段树的每个节点维护 su

线段树标记永久化

前言 对于树套树,主席树等使用到线段树的比较复杂的数据结构,如果区间修改的话,打标记后pushdown或者pushup是很难做到的完全不行吧 所以这个时候,一个神奇的东西诞生了... 正题 线段树标记永久化,维护一个标记,假设为cov,再维护一个sum 假设修改区间[ql, qr]全部加上v: 和平常一样,到这个区间后cov[x] += v 但是我们又不想pushup,怎么办? 很好做,更新的时候每次sum[x] += v * (qr - ql + 1) (注意这里的qr,ql是完全被包含于线段