【bzoj4636】蒟蒻的数列

由于数据范围过大,直接线段树会炸,离散化或者动态开点都行。

打个标记在树上,最后把树dfs一边算一下即可。

 1 #include<bits/stdc++.h>
 2 #define N 10000010
 3 #define inf 1000000000
 4 using namespace std;
 5 typedef long long ll;
 6 int tot=0,sumv[N<<2],ls[N],rs[N];
 7 int n,rt,cnt=0;ll ans=0;
 8 void change(int &o,int l,int r,int ql,int qr,int v){
 9     if(l>r)return;
10     if(!o)o=++cnt;
11     if(ql<=l&&r<=qr){sumv[o]=max(sumv[o],v);return;}
12     int mid=(l+r)>>1;
13     if(ql<=mid)change(ls[o],l,mid,ql,qr,v);
14     if(qr>mid)change(rs[o],mid+1,r,ql,qr,v);
15 }
16 void dfs(int o,int l,int r,int maxv){
17     if(!o)return;
18     maxv=max(maxv,sumv[o]);
19     if(!ls[o]&&!rs[o]){ans+=1LL*(r-l+1)*maxv;return;}
20     int mid=(l+r)>>1;
21     dfs(ls[o],l,mid,maxv);dfs(rs[o],mid+1,r,maxv);
22     if(!ls[o])ans+=1LL*(mid-l+1)*maxv;
23     if(!rs[o])ans+=1LL*(r-mid)*maxv;
24 }
25 inline int read(){
26     int f=1,x=0;char ch;
27     do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
28     do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
29     return f*x;
30 }
31 int main(){
32     n=read();
33     for(int i=1;i<=n;i++){
34         int l=read(),r=read(),k=read();
35         change(rt,0,inf,l,r-1,k);
36     }
37     dfs(rt,0,inf,0);
38     printf("%lld
",ans);
39     return 0;
40 }
原文地址:https://www.cnblogs.com/zcysky/p/6878208.html