概述
4636: 蒟蒻的数列
Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 618 Solved: 271
[Submit][Status][Discuss]
Description
蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列
题目描述
DCrusher有一个数列,初始值均为0,他进行N次操作,每次将数列[a,b)这个区间中所有比k小的数改为k,他想知
道N次操作后数列中所有元素的和。他还要玩其他游戏,所以这个问题留给你解决。
Input
第一行一个整数N,然后有N行,每行三个正整数a、b、k。
N<=40000 , a、b、k<=10^9
Output
一个数,数列中所有元素的和
Sample Input
4
2 5 1
9 10 4
6 8 2
4 6 3
2 5 1
9 10 4
6 8 2
4 6 3
Sample Output
16
HINT
Source
动态开点线段树与下标的传递,我们知道线段树的复杂度是2*n*longn,因为下标范围太大,所以我们要动态开点
所以对于n次询问我们可证明最多会新建2*n*logn个点 最后dfs一下求出总和即可
#include <bits/stdc++.h>
#define ll long long
#define inf 1e9
using namespace std;
inline int read(){
int x=0;int f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int MAXN=4e4+10;
int ls[MAXN*40],rs[MAXN*40],v[MAXN*40],t,tot,n,rt;
ll ans=0;
inline void insert(int &k,int l,int r,int x,int y){
if(!k){
k=++tot;
}
if(l==x&&r==y){
v[k]=max(v[k],t);return;
}
int mid=(l+r)>>1;
if(x>mid) insert(rs[k],mid+1,r,x,y);
else if(y<=mid) insert(ls[k],l,mid,x,y);
else insert(ls[k],l,mid,x,mid),insert(rs[k],mid+1,r,mid+1,y);
}
inline void query(int k,int l,int r,int x){
if(!k) return;
int mid=(l+r)>>1;
v[k]=max(v[k],x);
if(ls[k]) query(ls[k],l,mid,v[k]);
else ans+=1LL*(mid-l+1)*v[k];
if(rs[k]) query(rs[k],mid+1,r,v[k]);
else ans+=1LL*(r-mid)*v[k];
}
int main(){
n=read();
for(int i=1;i<=n;i++){
int x=read();int y=read();t=read();
if(x==y) continue;
insert(rt,1,inf,x,y-1);
}
query(rt,1,inf,0);
cout<<ans<<endl;
return 0;
}
转载于:https://www.cnblogs.com/something-for-nothing/p/9058336.html
最后
以上就是诚心百合为你收集整理的BZOJ 4636 蒟蒻的数列的全部内容,希望文章能够帮你解决BZOJ 4636 蒟蒻的数列所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复