描述

有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. eclipse xDoclet错误

    转载: http://blog.csdn.net/lovelongjun/article/details/53485773 Missing library: xdoclet-1.2.1.jar. Se ...

  2. 批量导入数据(Mysql)报MySQL server has gone away 问题的解决方法

    问题分析 首先度娘:mysql出现ERROR : (2006, 'MySQL server has gone away') 的问题意思就是指client和MySQL server之间的链接断开了. 造 ...

  3. fiddler 抓取 逍遥安卓模拟器 https包

    1.打开fiddler,进行相关设置 Tools--Fiddler Options 接下来进行客户端网络配置 1 查看电脑ip地址,ipconfig 逍遥游模拟器中使用自带的浏览器,访问192.168 ...

  4. window 下复制 cmd内容

    https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/windows_dos_copy.msp ...

  5. mysql安装笔记-rpm

    基本内容: 1.需要解决两个依赖 2.需要解决一个包冲突 3.安装mysql服务,以及客户端client 4.修改root的随机密码 5.授予root用户,从任何机器访问任何数据库的任何表的权限 1. ...

  6. date.getTime()

    Date date = new Date(); System.out.println(date.getTime()); 输出结果是1210745780625 编译时间当时时间大概是2008年5.14好 ...

  7. JDBC远程连接数据库

    使用jdbc远程连接数据库(非本地数据库)出现的问题可用的解决方法: 1.修改mysql配置文件 配置文件中注释掉 bind-address=127.0.0.1 2.修改数据库 登入mysql后,更改 ...

  8. keras—多层感知器MLP—MNIST手写数字识别

    一.手写数字识别 现在就来说说如何使用神经网络实现手写数字识别. 在这里我使用mind manager工具绘制了要实现手写数字识别需要的模块以及模块的功能:  其中隐含层节点数量(即神经细胞数量)计算 ...

  9. RigidBody组件的Is Kinematic

    RigidBody组件的Is Kinematic属性打上勾(设为true,使其不受物理引擎驱动,Wall是为了防止其移动,Person是为了防止其受到力不断旋转—看的心塞=v=) .is kinema ...

  10. error CS1010 CS8025 CS1012 CS1525 常见文档错误解决

    error CS1010: Newline in constant error CS8025: Parsing error error CS1012: Too many characters in c ...