生活随笔
收集整理的這篇文章主要介紹了
2081.09.22 Kuma(非旋treap)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
描述
有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;
}
轉載于:https://www.cnblogs.com/ldxcaicai/p/9738229.html
總結
以上是生活随笔為你收集整理的2081.09.22 Kuma(非旋treap)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。