描述

有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. as3 有趣现象 关于声明与变量

    当使用了一个变量,并且前后期都没有在有效域内对此声明,不管有没有赋值,都会报错. 但先使用了一个变量,后期在有效域内对此声明,那么此变量不报错,但在声明之前没有赋值,那么赋值默认值:如果使用变量时,赋 ...

  2. tcprstat分析服务的响应速度

    Tcprstat 是免费开源的TCP分析工具,可检测网络通信状态,并且计算请求和响应之间的延迟. 它的输出格式类似 linux 的 vmstat 和 iostat 的输出格式.这个工具能够检测到某个端 ...

  3. 【346】TF-IDF

    Ref: 文本挖掘预处理之向量化与Hash Trick Ref: 文本挖掘预处理之TF-IDF Ref: sklearn.feature_extraction.text.CountVectorizer ...

  4. nginx+redis+4个tomcat 负载均衡

    1,先配置nginx ,如果80接口被占用,且80 的端口又惹不起,参考:https://www.cnblogs.com/xiaohu1218/p/10267602.html 2,下载redis,并配 ...

  5. js中常用的事件

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  6. 条件语句;for循环 嵌套复习

    //打印数字,0,1,8,10,12,每一个数单独占一行 //在全部数字打印完毕之后在打印数字的个数和所有数的和 int count = 0; int sum = 0; for (int i = 0; ...

  7. Rabbitmq 基本属性

    MQ全称为Message Queue, 是一种分布式应用程序的的通信方法,它是消费-生产者模型的一个典型的代表,producer往消息队列中不断写入消息,而另一端consumer则可以读取或者订阅队列 ...

  8. 第七章 二叉搜索树(c)平衡与等价

  9. Python globals() 函数

    Python globals() 函数  Python 内置函数 描述 globals() 函数会以字典类型返回当前位置的全部全局变量. 语法 globals() 函数语法: globals() 参数 ...

  10. np.array()

    将列表list或元组tuple转换为 ndarray 数组. numpy.array(object, dtype=None, copy=True, order=None, subok=False, n ...