Bzoj4636] [Taccaの列番号[動的処方セグメントツリー]

bzoj4636 蒟蒻的数列

bzoj4636

DCrusherは列の数であり、初期値は0であり、N回の操作、各時間は、列の数は、[a、b)は、このセクションで、kにk個よりもすべて小さい、彼は列N操作の数をすべての要素を知りたいですそして、。

整数Nの最初の行は、N行、3つの正の整数、B、Kの各列があります。
N <= 40000、A、B 、K <= 10 ^ 9

テンプレート?

==この範囲内のすべての操作が完了した後、動的処方及びメンテナンスマークは確かに、すべてのマークを作るためにkに等価である最大数に等しいです。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define Max(x,y) ((x)>(y)?(x):(y))
#define lson (o<<1)
#define rson (o<<1|1)
const int N=40000+10,M=1e9,inf=0x3f3f3f3f;
int n,m,rt,tot;
ll ans=0;
template <class t>void rd(t &x){
    x=0;int w=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=w?-x:x;
}

struct node{int ls,rs,dat;}t[N<<2];

void upd(int &o,int l,int r,int x,int y,int k){
    if(l>y||r<x) return;
    if(!o) o=++tot;
    if(x<=l&&r<=y){t[o].dat=Max(t[o].dat,k);return;}
    int mid=l+r>>1;
    upd(t[o].ls,l,mid,x,y,k),upd(t[o].rs,mid+1,r,x,y,k);
}
void query(int o,int l,int r){
    if(!t[o].ls&&!t[o].rs){ans+=(ll)(r-l+1)*t[o].dat;return;}
    if(t[o].ls) t[t[o].ls].dat=Max(t[t[o].ls].dat,t[o].dat);
    if(t[o].rs) t[t[o].rs].dat=Max(t[t[o].rs].dat,t[o].dat);
    int mid=l+r>>1;
    if(t[o].ls) query(t[o].ls,l,mid);
    if(t[o].rs) query(t[o].rs,mid+1,r);
    if(!t[o].ls) ans+=(ll)(mid-l+1)*t[o].dat;
    if(!t[o].rs) ans+=(ll)(r-mid)*t[o].dat;
}

int main(){
    freopen("in.txt","r",stdin);
    //freopen("and.out","w",stdout);
    rd(n);
    for(int i=1,x,y,k;i<=n;++i){
        rd(x),rd(y),rd(k);
        if(x<=--y) upd(rt,1,M,x,y,k);
    }
    query(rt,1,M);
    printf("%lld",ans);
    return 0;
}

おすすめ

転載: www.cnblogs.com/lxyyyy/p/11461449.html