描述

有N张卡片,编号从0到n-1, 刚开始从0到n-1按顺序排好。

现有一个操作, 对于p、 l,表示从第p张卡片之后的l张卡片拿到 最前面。

例如n=7的时候, 刚开始卡片序列为0 1 2 3 4 5 6

对于操作p=2 l=3执行一次之后序列变为

2 3 4 0 1 5 6

求出所有操作之后, 奇数位上编号的和

输入

第一行两个整数 N、 M,表示有 N 张卡片,接下来 M 个操作。

接下来 M 行, 每行有三个整数 p、 l、 r, 表示重复 r 次 p、 l 操作。

输出

一个整数表示答案。

样例输入

10 3

5 3 1

2 4 1

7 2 2

样例输出

23

提示

对于 30%的数据, 1<=N,M<=1000。

对于 100%的数据, 1<=N<=1000000,1<=M<=5000,0<=p<=p+l< N

看到这个把一堆数放到队首的操作就想到了非旋treap。

要注意的是对于每次修改要利用题目给出的信息转化出新的询问区间。

还要注意答案开long long。

代码:

#include<bits/stdc++.h>
#define N 1000005
#define ll long long
using namespace std;
typedef pair<int,int> res;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
int n,m,cnt=0;
ll ans=0;
struct Treap{
	int rt,val[N],rd[N],son[N][2],siz[N],tot;
	inline int newnode(int v){val[++tot]=v,rd[tot]=rand(),siz[tot]=1;return tot;}
	inline void pushup(int p){siz[p]=siz[son[p][0]]+siz[son[p][1]]+1;}
	inline int merge(int a,int b){
		if(!a||!b)return a+b;
		if(rd[a]<rd[b])return son[a][1]=merge(son[a][1],b),pushup(a),a;
		return son[b][0]=merge(a,son[b][0]),pushup(b),b;
	}
	inline res split(int p,int k){
		if(!p)return make_pair(0,0);
		res tmp,ans;
		if(siz[son[p][0]]>=k){
			tmp=split(son[p][0],k),son[p][0]=tmp.second,pushup(p);
			ans.first=tmp.first,ans.second=p;
			return ans;
		}
		tmp=split(son[p][1],k-siz[son[p][0]]-1),son[p][1]=tmp.first,pushup(p);
		ans.first=p,ans.second=tmp.second;
		return ans;
	}
	inline void dfs(int p){
		if(!p)return;
		dfs(son[p][0]);
		if((++cnt)&1)ans+=val[p];
		dfs(son[p][1]);
	}
	inline int build(int l,int r){
		if(l>r)return 0;
		int mid=l+r>>1,p=newnode(mid);
		son[p][0]=build(l,mid-1),son[p][1]=build(mid+1,r);
		pushup(p);
		return p;
	}
	inline void solve(){
		srand(time(NULL));
		n=read(),m=read();
		rt=build(0,n-1);
		while(m--){
			int pos=read(),l=read(),r=read(),L,R;
			R=pos+l-1,L=(R+1-l*r)%(R+1);
			if(L<0)L+=R+1;
			if(L>R)continue;
			R-=L-1;
			res x=split(rt,L),y=split(x.second,R);
			rt=merge(y.first,merge(x.first,y.second));
		}
		dfs(rt);
		cout<<ans;
	}
}T;
int main(){
	T.solve();
	return 0;
}

2081.09.22 Kuma(非旋treap)的更多相关文章

  1. 非旋 treap 结构体数组版(无指针)详解,有图有真相

    非旋  $treap$ (FHQ treap)的简单入门 前置技能 建议在掌握普通 treap 以及 左偏堆(也就是可并堆)食用本blog 原理 以随机数维护平衡,使树高期望为logn级别, FHQ  ...

  2. [模板] 平衡树: Splay, 非旋Treap, 替罪羊树

    简介 二叉搜索树, 可以维护一个集合/序列, 同时维护节点的 \(size\), 因此可以支持 insert(v), delete(v), kth(p,k), rank(v)等操作. 另外, prev ...

  3. 平衡树简单教程及模板(splay, 替罪羊树, 非旋treap)

    原文链接https://www.cnblogs.com/zhouzhendong/p/Balanced-Binary-Tree.html 注意是简单教程,不是入门教程. splay 1. 旋转: 假设 ...

  4. 2827: 千山鸟飞绝 非旋treap

    国际惯例的题面:看起来很不可做的样子,我们先来整理一下题意吧.就是,维护每个点曾经拥有过的最大的两个属性值,支持把点的位置移动.我们用map对每个位置进行离散化,对每个位置建立一个平衡树.为了方便分离 ...

  5. 2018.08.27 rollcall(非旋treap)

    描述 初始有一个空集,依次插入N个数Ai.有M次询问Bj,表示询问第Bj个数加入集合后的排名为j的数是多少 输入 第一行是两个整数N,M 接下来一行有N个整数,Ai 接下来一行有M个整数Bj,保证数据 ...

  6. 2018.08.06 bzoj1500: [NOI2005]维修数列(非旋treap)

    传送门 平衡树好题. 我仍然是用的fhqtreap,感觉速度还行. 维护也比线段树splay什么的写起来简单. %%%非旋treap大法好. 代码: #include<bits/stdc++.h ...

  7. 2018.08.05 bzoj3223: Tyvj 1729 文艺平衡树(非旋treap)

    传送门 经典的平衡树问题,之前已经用splay写过一次了,今天我突发奇想,写了一发非旋treap的版本,发现挺好写的(虽然跑不过splay). 代码: #include<bits/stdc++. ...

  8. 2018.07.24 loj#107. 维护全序集(非旋treap)

    传送门 就是普通平衡树,可以拿来练非旋treap" role="presentation" style="position: relative;"&g ...

  9. 2018.07.06 BZOJ 1588: HNOI2002营业额统计(非旋treap)

    1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MB Description 营业额统计 Tiger最近被公司升任为营业部经理,他上 ...

随机推荐

  1. Screen Monitors

    Screen Screen->MonitorCount Monitors Screen->FormCount Screen->Forms[I]->Name

  2. MDAC 重新安装

    MDAC 重新安装 c:\windows\inf 下找出mdac.inf 然后点右键->安装

  3. 机器学习入门-随机森林温度预测-增加样本数据 1.sns.pairplot(画出两个关系的散点图) 2.MAE(平均绝对误差) 3.MAPE(准确率指标)

    在上一个博客中,我们构建了随机森林温度预测的基础模型,并且研究了特征重要性. 在这个博客中,我们将从两方面来研究数据对预测结果的影响 第一方面:特征不变,只增加样本的数据 第二方面:增加特征数,增加样 ...

  4. ios tableview header 透明

    当将tableview的style属性设为grouped时,header或footer会变成透明,如果设为plain,header或footer会保持默认颜色

  5. mysql查看进程

    select * from information_schema.processlist 查询所有连接到数据库的进程信息.

  6. python内存泄漏

    记录: 一个脚本在连续运行后,使用内存越来越大,在循环后手动添加gc.collect()没有作用. 尝试方法: 去除所有函数中当作参数传入的全局变量 使用全局redis对象,不再当作参数传入 循环末尾 ...

  7. HttpClient 超时时间

    setSoTimeout(MilSec):连接超时时间.如果在连接过程中有数据传输,超时时间重新计算. setConnectTimeout(MilSec):获取连接超时时间.如果该参数没有设置,那么默 ...

  8. ContextLoaderListener和Spring MVC中的DispatcherServlet学习

    DispatcherServlet介绍 DispatcherServlet是Spring前端控制器的实现,提供Spring Web MVC的集中访问点,并且负责职责的分派,与Spring IoC容器无 ...

  9. Ajax 与 jquery

    jquery 里面的ajax用法: $.ajax({ 参数设置: 如果返回数据不是json的时候,记得转化为json . var data = json.parse(data); json 可以直接点 ...

  10. 使用Navicat Premium连接mysql数据库

    Navicat Premium是一个可多重连接的数据库管理工 具,它可让你以单一程序同时连接. Navicat Premium 使你能简单并快速地在各种数据库系统间传输数据,或传输一份指定 SQL 格 ...