[codeforces896E] Welcome home, Chtholly

浅谈珂朵莉树(ODT) 浅谈珂朵莉树(Chtholly Tree) What is Chtholly Tree? Chtholly tree,别称Old Driver Tree(ODT),一种暴力+玄学的数据结构,起源于CodeFoeces平台上编号为896C的一道题—— “ Willem, Chtholly and Seniorious ”。一位用户Old Driver在给出了线段树的正解之后,又发布了一份前所未有的玄学解法,其中利用到的数据结构就是今日我们 喜闻乐见的 珂朵莉树。 珂朵莉树本质上是一个二叉平衡树,每一个节点p( 阅读详情

题目大意

给定一个n个数的序列。m次操作:1. 给区间[l,r]中所有大于x的数减x 2. 询问区间[l,r]中数值为x的数个数。

n,m≤100000 1≤a[i],x≤100000

分析

这题?循环展开然后optimize一下就过了

这是由乃题,我们应该考虑分块。

值域范围比较小,我们可以直接记录cnt[i][j]表示块i中数值为j的数个数。
然后再用并查集把同一块中数值相同的元素缩在一起。
对于第一个操作:首先两边的散块可以暴力修改。
对于中间的块:设mx表示该块中的最大值。分以下几种情况:
1. x≥mx,此时不用做任何修改
2. x < mx < 2*x,此时可以暴力把区间[x+1,mx]和[1,mx-x]对应的元素合并
3. 2*x≤mx,我们注意到:第一个操作等价于先把所有元素减x,然后把小于等于0的加x。所以我们可以设一个tag[i]表示块i中这种情况减少的总数。对于这种情况,先暴力把区间[1,x]和[x+1,x+x]对应的元素合并,然后tag[i]+=x

第二个操作:两边的散块暴力查询,中间的ans+=cnt[i][x+tag[i]]即可。

我们发现,对于修改操作:每一块合并的次数不超过100000次。
所以整体时间复杂度是O(mn√)

#include <cstdio>
#include <cstring>
#include <algorithm>

#define max(a,b) ((a)>(b)?(a):(b))

using namespace std;

const int N=1e5+5,G=320;

typedef long long LL;

int n,m,f[N],cnt[N],Id[N],val[N],b[N],tag[G],a[314][N],mx[G],ans;

char c;

int read()
{
    int x=0,sig=1;
    for (c=getchar();c<'0' || c>'9';c=getchar()) if (c=='-') sig=-1;
    for (;c>='0' && c<='9';c=getchar()) x=x*10+c-48;
    return x*sig;
}

int Get(int x)
{
    return (f[x]==x)?x:f[x]=Get(f[x]);
}

void Merge(int x,int y)
{
    f[y]=x; cnt[x]+=cnt[y];
}

void Change1(int l,int r,int x)
{
    int i,j;
    for (j=l;Id[j-1]==Id[j];j--);
    for (i=j;Id[i]==Id[r];i++)
    {
        b[i]=val[Get(i)]; a[Id[i]][b[i]]=0;
    }
    mx[Id[r]]=0;
    for (i=l;i<=r;i++) if (b[i]-tag[Id[i]]>x) b[i]-=x;
    for (i=j;Id[i]==Id[r];i++)
    {
        f[i]=i; cnt[i]=1; val[i]=b[i];
        mx[Id[i]]=max(mx[Id[i]],val[i]);
        if (!a[Id[i]][val[i]]) a[Id[i]][val[i]]=i;else Merge(a[Id[i]][val[i]],i);
    }
}

void Change2(int l,int r,int x)
{
    for (int i,j=l;j<=r;j++) if (tag[j]+x<mx[j])
    {
        if (tag[j]+(x<<1)<=mx[j])
        {
            for (i=tag[j]+x;i>tag[j];i--) if (a[j][i])
            {
                if (!a[j][i+x]) val[a[j][i+x]=a[j][i]]=i+x;else Merge(a[j][i+x],a[j][i]);
                a[j][i]=0;
            }
            tag[j]+=x;
        }else
        {
            for (i=tag[j]+x+1;i<=mx[j];i++) if (a[j][i])
            {
                if (!a[j][i-x]) val[a[j][i-x]=a[j][i]]=i-x;else Merge(a[j][i-x],a[j][i]);
                a[j][i]=0;
            }
            for (i=tag[j]+x;!a[j][i];i--);
            mx[j]=i;
        }
    }
}

int main()
{
    n=read(); m=read();
    for (int i=1;i<=n;i++)
    {
        Id[i]=i/G; f[i]=i; cnt[i]=1;
        val[i]=read(); mx[Id[i]]=max(mx[Id[i]],val[i]);
        if (!a[Id[i]][val[i]]) a[Id[i]][val[i]]=i;else Merge(a[Id[i]][val[i]],i);
    }
    Id[0]=Id[n+1]=-1;
    for (int typ,l,r,x,i;m--;)
    {
        typ=read(); l=read(); r=read(); x=read();
        if (typ==1)
        {
            if (Id[l]==Id[r])
            {
                Change1(l,r,x);
                continue;
            }
            for (i=l;Id[i+1]==Id[l];i++);
            Change1(l,i,x);
            for (i=r;Id[i-1]==Id[r];i--);
            Change1(i,r,x);
            Change2(Id[l]+1,Id[r]-1,x);
        }else
        {
            ans=0;
            if (Id[l]==Id[r])
            {
                for (i=l;i<=r;i++) ans+=(val[Get(i)]-tag[Id[i]]==x);
            }else
            {
                for (i=l;Id[i]==Id[l];i++) ans+=(val[Get(i)]-tag[Id[i]]==x);
                for (i=r;Id[i]==Id[r];i--) ans+=(val[Get(i)]-tag[Id[i]]==x);
                for (i=Id[l]+1;i<Id[r];i++) if (x+tag[i]<N) ans+=cnt[a[i][x+tag[i]]];
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}
CF 896C - Willem, Chtholly and Seniorious (珂朵莉树) 给 nnn 个整数 {ai}\{a_i\}{ai​},进行 mmm 次操作,操作类型如下: 1 l r x :区间 [l,r] 上每个数 +x 2 l r x :区间 [l,r] 上每个数 =x 3 l r x :区间 [l,r] 上第 x 小的数 4 l r x y:计算 (∑i=lraix) mod y(\sum_{i=l}^ra_i^x)\bmod y(∑i=lr​aix​)mody 输入为 n,m,seed,v_max ,根据以下函数来生成 {ai}\{a_i\}{ai​} 以及每次的具体操作: 阅读详情

相关推荐

【Linux】Petalinux使用QSPI FLASH引导启动

1. 预分配Flash空间使用Flash引导Petalinux做的系统,也有进阶的做法。部分图片和经验来源于网络,若有侵权麻烦联系我删除,主要是做笔记的时候忘记写来源了,做完笔记很久才写博客。1. 预分配Flash空间根据生成的bit文件大小估算BOOT.BIN文件的大小,为Flash大概分配四个分区:boot、bootenv、kernel、bootscr,分别存放BOOT.BIN文件、u-boot的环境变量、内核文件(image.ub/zImage/uImage等)、启动脚本boot.scr。

Tesseract_9527的博客 3374

Codeforces Round #449 (Div. 1) E. Welcome home, Chtholly

E. Welcome home, Chtholly time limit per test3 seconds memory limit per test512 megabytes inputstandard input outputstandard output — I… I survived.— Welcome home, Chtholly.— I kept my promise…— I

zstu_zy的博客 419

DreamerV3实战:如何用世界模型在Minecraft中自动挖钻石(附完整训练流程)

本文详细介绍了如何使用DreamerV3世界模型在Minecraft中训练AI智能体自动完成挖钻石的复杂任务。文章深入分析了该任务对强化学习的挑战,提供了从环境配置、模型训练到结果评估的完整实战流程,并分享了关键的调优技巧与问题解决方案,展示了基于模型的强化学习在解决稀疏奖励问题上的强大能力。

weixin_29050271的博客 189

浅谈珂朵莉树(Chtholly Tree)——暴力而玄学的数据结构

关于它很珂学的名字… 珂朵莉树(Chtholly Tree),又称老司机树(Old Driver Tree),起源于CodeFoeces平台上编号为896C的一道题—— “ Willem, Chtholly and Seniorious ” (珂学家们此时不用翻译也知道这个名字是在说啥了) ,一位用户Old Driver在给出了线段树的正解之后,又发布了YY多年的 一份前所未有的玄学解法,其中利用......

CC_dsm的博客 2万+

TwinCAT3与Matlab Simulink集成开发:如何快速生成和调试TcCOM模块

本文详细介绍了如何将TwinCAT3与Matlab Simulink进行深度集成,实现从控制算法模型到实时TcCOM模块的高效开发。通过环境搭建、模型配置、代码生成、系统集成与调试的完整流程,工程师可以快速将Simulink算法部署到倍福实时控制平台,大幅缩短开发周期并提升可靠性。

ik67890123的博客 223

【CF896E】Welcome home, Chtholly 暴力+分块+链表

【CF896E】Welcome home, Chtholly 题意:一个长度为n的序列ai,让你支持两种操作: 1.l r x:将[l,r]中ai>x的ai都减去x。2.l r x:询问[l,r]中有多少ai=x。 n,m<=100000,ai,x<=100000。 题解:先分块,对于每一块,我们用双向链表维护块内所有不同的ai的值(排好序的);对于每个ai的值...

aodanchui1057的博客 440

FPGA实现16x16点阵汉字滚动显示:Verilog代码与Quartus仿真详解

本文详细介绍了如何使用FPGA实现16x16点阵汉字滚动显示,包括Verilog代码设计、Quartus仿真及硬件连接技巧。通过字模数据存储和扫描控制逻辑,实现汉字的动态显示效果,并提供了优化建议和常见问题解决方案,适合FPGA开发者和硬件爱好者学习参考。

weixin_29172963的博客 349

洛谷10月月赛R2·浴谷八连测R3 -Chtholly- 1、2题题解

比赛题解

TYB的博客 415

Android wifi源码分析(二) Wifi关闭流程

接着上一篇,这篇说一下Wifi的关闭流程。 由上一篇可以知道,framework层提供的wifi开关接口都是**setWifiEnabled**,只是参数不同而已。*true*表示开启wifi、*false*表示关闭wifi。

奋斗的菜鸟ing 3297

学习心得——COMSOL Multiphysics with MATLAB联合仿真及寻优计算

学习心得——COMSOL Multiphysics with MATLAB联合仿真及寻优计算

weixin_41678956的博客 8657

【Codeforces 896E】—Welcome home, Chtholly(分块)

传送门 这个东西线段树没啥好办法维护 考虑分块 对于每个块每个权值维护一个并查集并且维护一下sizsizsiz 考虑一次修改 如果一个整块值域&gt;2x&gt;2x>2x 就把[1,x][1,x][1,x]向上合并,再整体打上标记 否则把[x+1,mx][x+1,mx][x+1,mx]向下合并 这样可以在O(x)O(x)O(x)的时间内把值域减小xxx 对于散块暴力重构 复...

Stargazer的博客 516

【异常】OpenClaw 项目 `fetch failed` 报错问题排查与解决方案Response interrupted: TypeError: fetch failed

针对无超时控制、异常兜底缺失导致的请求中断,封装标准化的安全请求工具,一次性解决超时控制、异常捕获、日志埋点三大问题,全项目替换原生。:将项目运行的 Node.js 版本升级至 18.x 及以上 LTS 版本,使用 Node.js 内置的稳定版。实现的网络请求环节,包括但不限于:第三方开放接口调用、内部服务接口通信、跨域资源请求、外部配置拉取等场景。:针对无法升级 Node.js 版本的存量环境,通过社区稳定兼容包替换原生。类型异常,直接造成业务请求响应中断。第二步:业务代码改造,替换原生。

奶爸的编程之路,也就一周冷个三天 366

Codeforces 896E Welcome home, Chtholly 分块+并查集

题意 给出一个长度为n序列A,要求支持m个操作: 1 l r x对于区间[l,r]中所有大于x的位置,将其减去x 2 l r x查询区间[l,r]中有多少个位置的值恰好为x n,m,A[i],x 分析 首先需要大力分块一波。 对于每一个块,我们将权值相同的位置用并查集搞在一起,并维护一个tagtag表示整块的值要减去多少,mxmx表示块内最大值。 对于操作1: 首先两边的块可以暴

beginend 699

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

珂朵莉树/老司机树学习笔记

珂朵莉树/老司机树学习笔记

Legg 的博客 1153

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

【CF896E】Welcome home, Chtholly(分块)(并查集)

传送门 题解: 分块。 由于值域很小,考虑用并查集维护块内相同的数个数以及当前的值,整块修改的时候只需要看一下当前块的值域RRR是否大于两倍当前的修改参数vvv,如果R≥v∗2R\geq v*2R≥v∗2,则我们将[1,v][1,v][1,v]的并查集向上合并并打标记,否则我们将上面的向下合并,于是我们可以在O(a)O(a)O(a)的时间内将值域大小减少aaa,均摊复杂度是对的。 操作常数,整块...

zxyoi_dreamer的博客(不定期诈尸) 420

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

珂朵莉树(Chtholly Tree)学习笔记

珂朵莉树(Chtholly Tree)学习笔记 珂朵莉树原理 其原理在于运用一颗树(set,treap,splay......)其中要求所有元素有序,并且支持基本的操作(删除,添加,查找......)来实现区间压缩。 那么区间压缩的意义在于区间推平这是珂朵莉树的核心(如果没有这个操作实际上不一定需要这种算法) ps:若保证有连续相等甚至递增的区间,也可以的(吧?)。 可想而知它的操作在于对区...

weixin_30248399的博客 316

Codeforces #449 Div.1 E: Welcome home, Chtholly(分块+并查集)

传送门题意: 给一个序列,支持如下操作: 1.l,r,x a[l~r]所有大于x的数减去x 2.l,r,x 查询a[l~r]中x的个数。 n,l,r,x≤1e5n,l,r,x\le 1e5题解:好妙的一道题。。记一个块的最大值(不超过O(n)O(n))。并查集维护每个块中的所有权值。每次修改时判断当前修改的值的两倍是否大于当前块的最大值。若不大于,则暴力修改小的部分(小的部分+v)并打修改标

DZYO的博客 438

CF896E Welcome home, Chtholly(暴力卡常)

AC⁡=O(nm)+快读+循环展开+指针+优化开关\operatorname{AC} = O(nm) + \text{快读} + \text{循环展开} + \text{指针} + \text{优化开关}AC=O(nm)+快读+循环展开+指针+优化开关 时间复杂度 O(松)O(\text{松})O(松) #pragma comment(linker, "/stack:200000000") #pragma GCC optimize("Ofast") #pragma GCC target("sse,sse2,

ylxmf2005's Blog 1138

Chtholly Tree (珂朵莉树) ODT

ODT,OldDriverTree,又名ChthollyTreeODT,OldDriverTree,又名ChthollyTreeODT ,Old Driver Tree,又名 Chtholly Tree −关键操作推平一段区间−关键操作推平一段区间 - 关键操作 推平一段区间 1. CF 896C Willem, Chtholly and Seniorious #include...

Bryce1010's Blog 4518

CF896E Welcome home, Chtholly(分块/并查集/第二分块)

CF896E Welcome home, Chtholly 对于给定一个长度为n(n<=1e5)的序列,值域范围为1e5,要求支持两类操作。 将区间[l,r]内所有大于x的数减x 查询区间[l,r]内值为x的数的个数 首先由于n和值域同阶,所以我们应该在值域上进行操作,但是这个东西不好用线段树的结构维护,因为它的修改比较独特,我们难以标记下传的方式处理。 但是我们可以使用分块暴力处理,然后因为操作一的复杂度与值域有关,我们可以看出来,因为只有减操作,所以最大值一定是单调递减的,然后我们可以做到维护

xajd1906的博客 461

[ 数论 ] Codeforces896D

枚举VIP的个数 xx,求出第一种人个数的范围 [L,R][L,R]。 用类似求卡特兰数的方法可以求出答案为 (nx)∑i=LR(n−xi)−(n−xi+1){n\choose x}\sum_{i=L}^R {n-x\choose i}-{n-x\choose i+1} 即 (nx)⋅(n−xL)−(nx)⋅(n−xR+1){n\choose x}·{n-x\choose L}-{n\cho

gjghfd 597

致——世界上最幸福的女孩——Chtholly

世界上最幸福的女孩——Chtholly

白夕の旅途 8877

Codeforces Round #449 (Div. 1) B. Ithea Plays With Chtholly set维护最小值

B. Ithea Plays With Chtholly time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard output This is an interactive problem. Refer to the Interaction secti

zstu_zy的博客 716

区间翻转问题 Splay

NKOJ 2504 区间翻转问题问题描述 给你一个长度为N的序列{ai}和M个操作 1.查询第k个数的值 2.将第k个数增加d 3.查询一段区间的和 4.查询一段区间的最大值 5.将一段区间镜面翻转(例如序列{1,2,3,4,5,6},将从2到5的区间翻转后得到序列{1,5,4,3,2,6}) 对于除操作2,5以外的操作,输出相应的答案 输入格式 第一行两

rgnoH的博客 1152

[ODT] Codeforces 896C. Willem, Chtholly and Seniorious

据ODT在CF上说,是一种叫ODT的树用平衡树维护区间,暴力修改维护这些区间。因为数据随机,所以跑得快…发现自己不会用SET………#include <cstdio> #include <iostream> #include <algorithm> #include <set> #include <map> #include <vector> #include <assert.h> #define m

CE玩家 721
上一篇: [bzoj5011][Jx2017]颜色
下一篇: GDKOI游记
WorldWide_D
博客等级 码龄11年 63粉丝 203原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值