描述

有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. 在Textbox中按回车键后继续获取焦点

    textbox的值为空或没有更改时,按下回车键textbox会失去焦点 此时用textbox1.setfocus不能使textbox1重新获取焦点 Private Sub Textbox1_KeyDo ...

  2. Mysql 唯一性约束添加

    来自:  http://blog.csdn.net/yumushui/article/details/38960619 一.单列唯一约束 在一列上添加唯一约束,主要是让该列在表中只能有唯一的一行,例如 ...

  3. jsfl 改变舞台宽高

    fl.getDocumentDOM().height= 680; fl.getDocumentDOM().width= 550;

  4. nginx 无法访问root权限的文件内容

    问题: 按照的nginx,nginx配置的user  是 nginx,nginx 是root用户启动的.  文件夹A放的那啥是root用户上传的文件. 可 nginx 无法访问 到  文件. 方法: ...

  5. ADO数据库编程入门

    ADO 是目前在Windows环境中比较流行的客户端数据库编程技术. ADO是建立在OLE DB底层技术之上的高级编程接口,因而它兼具有强大的数据处理功能(处理各种不同类型的数据源.分布式的数据处理等 ...

  6. 趣味编程:CPS风格代码(Java 8,Functional Java版)

    CPS风格代码(Java 8版) package fp; import java.util.function.IntConsumer; public class CPS { static int ad ...

  7. 岭回归和lasso回归(转)

    回归和分类是机器学习算法所要解决的两个主要问题.分类大家都知道,模型的输出值是离散值,对应着相应的类别,通常的简单分类问题模型输出值是二值的,也就是二分类问题.但是回归就稍微复杂一些,回归模型的输出值 ...

  8. Redis事务的简单理解

    Redis事务的命令如下所示: 先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令 示例如下: //开始一个事务 > MU ...

  9. 123. Best Time to Buy and Sell Stock III (Array; DP)

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  10. QT隐式数据共享

    QT中许多C++类使用了隐式数据共享,最小化资源拷贝.当作为参数传递时,实际只传递了指针,这是底层完成的,程序员无需担心,即使是在多线程中,从Qt4开始: 记住,尽量使用const迭代器,vector ...