复习计划-线段树

  • 线段树维护区间和,区间更新乘与加
    需要注意lazy标记的更新顺序
  • 经典例题 P3373
//#define LOCAL
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define mem(a, b) memset(a,b,sizeof(a))
#define sz(a) (int)a.size()
#define INF 0x3f3f3f3f
#define DNF 0x7f
#define DBG printf("this is a input\n")
#define fi first
#define se second
#define mk(a, b) make_pair(a,b)
#define pb push_back
#define LF putchar('\n')
#define SP putchar(' ')
#define p_queue priority_queue
#define CLOSE ios::sync_with_stdio(0); cin.tie(0)

template<typename T>
void read(T &x) {x = 0;char ch = getchar();ll f = 1;while(!isdigit(ch)){if(ch == '-')f *= -1;ch = getchar();}while(isdigit(ch)){x = x * 10 + ch - 48; ch = getchar();}x *= f;}
template<typename T, typename... Args>
void read(T &first, Args& ... args) {read(first);read(args...);}
template<typename T>
void write(T arg) {T x = arg;if(x < 0) {putchar('-'); x =- x;}if(x > 9) {write(x / 10);}putchar(x % 10 + '0');}
template<typename T, typename ... Ts>
void write(T arg, Ts ... args) {write(arg);if(sizeof...(args) != 0) {putchar(' ');write(args ...);}}
using namespace std;

ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a % b);
}

ll lcm(ll a, ll b) {
    return a / gcd(a, b) * b;
}
const int N = 1e5 + 5;
int n , m , mod;
struct node {
   int l , r;
   ll sum , alz, mlz;
}tree[N * 4];
int input[N];
void build (int i , int l , int r)
{
    tree[i].l = l;
    tree[i].r = r;
    tree[i].mlz = 1 , tree[i].alz = 0;
    if (l == r)
    {
        tree[i].sum = input[l]%mod;
        return ;
    }
    int mid = (l + r) >> 1;
    build (i << 1 , l , mid);
    build (i << 1 | 1 , mid + 1, r);
    tree[i].sum = (tree[i << 1].sum + tree[i << 1 | 1].sum)%mod;
}
void pushdown (int i)
{
    tree[i*2].sum = (1ll * (tree[i].mlz * tree[i*2].sum)%mod + (1ll * (tree[i*2].r-tree[i*2].l+1) * tree[i].alz)%mod)%mod;
    tree[i*2+1].sum = (1ll * (tree[i].mlz * tree[i*2+1].sum)%mod + (1ll*(tree[i*2+1].r-tree[i*2+1].l+1)*tree[i].alz)%mod)%mod;

    tree[i*2].mlz = 1ll*(tree[i*2].mlz*tree[i].mlz)%mod;
    tree[i*2+1].mlz = 1ll*(tree[i*2+1].mlz*tree[i].mlz)%mod;

    tree[i*2].alz=1ll*(tree[i*2].alz*tree[i].mlz+tree[i].alz)%mod;
    tree[i*2+1].alz=1ll*(tree[i*2+1].alz*tree[i].mlz+tree[i].alz)%mod;

    tree[i].mlz=1,tree[i].alz=0;

}
void Aupdate (int i , int l , int r, int k)
{
    if (tree[i].l >= l && tree[i].r <= r)
    {
        tree[i].alz += k;
        tree[i].alz %= mod;
        tree[i].sum += 1ll * (tree[i].r - tree[i].l + 1) * k;
        tree[i].sum %= mod;
        return ;
    }
    pushdown(i);
    int mid = (tree[i].l + tree[i].r) >> 1;
    if (l <= mid) Aupdate(i << 1, l , r, k);
    if (r >  mid) Aupdate (i << 1 | 1 , l , r, k);
    tree[i].sum = (tree[i << 1].sum + tree[i << 1 | 1].sum)%mod;
}
void Mupdate (int i , int l , int r, int k)
{
    if (tree[i].l >= l && tree[i].r <= r)
    {
        tree[i].alz = (tree[i].alz * k) % mod;
        tree[i].mlz = (tree[i].mlz * k) % mod;
        tree[i].sum = (tree[i].sum * k) % mod;
        return ;
    }
    pushdown(i);
    int mid = (tree[i].l + tree[i].r) >> 1;
    if (l <= mid) Mupdate(i << 1 , l , r, k);
    if (r >  mid) Mupdate (i << 1 | 1 , l , r, k);
    tree[i].sum = (tree[i << 1].sum + tree[i << 1 | 1].sum) % mod;
}

ll query(int i , int l ,int r)
{
    if(tree[i].l>=l && tree[i].r<=r){
        return tree[i].sum;
    }
    pushdown(i);
    ll val = 0;
    int mid = (tree[i].l+tree[i].r)>>1;
    if(l <= mid)val = (val + query(i*2,l,r))%mod;
    if(mid < r)val = (val + query(i*2+1,l,r))%mod;
    return val;
}
int main (void)
{
    read (n , m, mod);
    for (int i = 1 ; i <= n ; i ++)
        read (input[i]);
    build (1, 1, n);
    while (m --)
    {
        int op , x , y , k;
        read (op);
        if (op == 1)
        {
            read (x , y, k);
            Mupdate(1,x,y,k);
        }
        else if (op == 2)
        {
            read (x, y , k);
            Aupdate(1,x,y,k);
        }
        else
        {
            read (x , y);
            cout << query(1,x,y) << endl;
        }
    }
}
  • 线段树区间合并,一般将区间分割为前缀,后缀,当前属性之类
    经典例题:P6492
//#define LOCAL
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define mem(a, b) memset(a,b,sizeof(a))
#define sz(a) (int)a.size()
#define INF 0x3f3f3f3f
#define DNF 0x7f
#define DBG printf("this is a input\n")
#define fi first
#define se second
#define mk(a, b) make_pair(a,b)
#define pb push_back
#define LF putchar('\n')
#define SP putchar(' ')
#define p_queue priority_queue
#define CLOSE ios::sync_with_stdio(0); cin.tie(0)

template<typename T>
void read(T &x) {x = 0;char ch = getchar();ll f = 1;while(!isdigit(ch)){if(ch == '-')f *= -1;ch = getchar();}while(isdigit(ch)){x = x * 10 + ch - 48; ch = getchar();}x *= f;}
template<typename T, typename... Args>
void read(T &first, Args& ... args) {read(first);read(args...);}
template<typename T>
void write(T arg) {T x = arg;if(x < 0) {putchar('-'); x =- x;}if(x > 9) {write(x / 10);}putchar(x % 10 + '0');}
template<typename T, typename ... Ts>
void write(T arg, Ts ... args) {write(arg);if(sizeof...(args) != 0) {putchar(' ');write(args ...);}}
using namespace std;

ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a % b);
}

ll lcm(ll a, ll b) {
    return a / gcd(a, b) * b;
}
const int N = 3e5 + 5;
int n , m;
struct node {
    int l , r;
    int v , lv , rv;
    int lc , rc;
}tree[N * 4];
void pushup (int i)
{
    int L_len = tree[i<<1].r - tree[i<<1].l + 1;
    int R_len = tree[i<<1|1].r - tree[i<<1|1].l + 1;

    if (tree[i<<1].lv == L_len && tree[i<<1].rc != tree[i<<1|1].lc)
        tree[i].lv = L_len + tree[i<<1|1].lv;
    else
        tree[i].lv = tree[i<<1].lv;
    tree[i].lc = tree[i<<1].lc;

    if (tree[i<<1|1].rv == R_len && tree[i<<1|1].lc != tree[i<<1].rc)
        tree[i].rv = R_len + tree[i<<1].rv;
    else
        tree[i].rv = tree[i<<1|1].rv;

    tree[i].rc = tree[i << 1 | 1].rc;

    tree[i].v = 1;
    tree[i].v = max (tree[i].v , tree[i<<1].v);
    tree[i].v = max (tree[i].v , tree[i<<1|1].v);
    tree[i].v = max (tree[i].v , tree[i].lv);
    tree[i].v = max (tree[i].v , tree[i].rv);
    if (tree[i<<1|1].lc != tree[i<<1].rc)
        tree[i].v = max (tree[i].v , tree[i<<1].rv + tree[i<<1|1].lv);

}
void build (int i , int l , int r)
{
    tree[i].l = l , tree[i].r = r;
    tree[i].v = tree[i].lv = tree[i].rv = 1;
    tree[i].lc = tree[i].rc = 1;
    if (l == r)
        return ;
    int mid = (l + r) >> 1;
    build (i<<1, l, mid);
    build (i<<1|1, mid + 1, r);
    pushup (i);
}
void update (int i , int k)
{
    if (tree[i].l == tree[i].r)
    {
        if (tree[i].lc == 1)
            tree[i].lc = tree[i].rc = 0;
        else
            tree[i].lc = tree[i].rc = 1;
        return ;
    }
    int mid = (tree[i].l + tree[i].r) >> 1;
    if (k <= mid)
        update (i << 1 , k);
    else
        update (i << 1 | 1, k);
    pushup(i);
}
void dbg (int i)
{
    cout << tree[i].l << ' ' << tree[i].r << ' ' << tree[i].v << endl;
    cout << tree[i].lc << ' ' << tree[i].rc << ' ' << tree[i].lv << ' ' << tree[i].rv << endl;
    if (tree[i].l == tree[i].r)
        return ;
    dbg (i << 1);
    dbg (i << 1 | 1);
}
int main (void)
{
    read (n , m);
    build (1, 1, n);
    while (m --)
    {
        int x ;
        read (x);
        update (1, x);
        //dbg(1);
        //cout << "----------------------------------" << endl;
        write (tree[1].v),LF;
    }
}
  • 三元组计数问题(动态开点权值线段树 或者 离散化+权值线段树),左边统计一下,右边统计一下,先query后insert就行
  • 经典例题:P1637
//#define LOCAL
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define mem(a, b) memset(a,b,sizeof(a))
#define sz(a) (int)a.size()
#define INF 0x3f3f3f3f
#define DNF 0x7f
#define DBG printf("this is a input\n")
#define fi first
#define se second
#define mk(a, b) make_pair(a,b)
#define pb push_back
#define LF putchar('\n')
#define SP putchar(' ')
#define p_queue priority_queue
#define CLOSE ios::sync_with_stdio(0); cin.tie(0)

template<typename T>
void read(T &x) {x = 0;char ch = getchar();ll f = 1;while(!isdigit(ch)){if(ch == '-')f *= -1;ch = getchar();}while(isdigit(ch)){x = x * 10 + ch - 48; ch = getchar();}x *= f;}
template<typename T, typename... Args>
void read(T &first, Args& ... args) {read(first);read(args...);}
template<typename T>
void write(T arg) {T x = arg;if(x < 0) {putchar('-'); x =- x;}if(x > 9) {write(x / 10);}putchar(x % 10 + '0');}
template<typename T, typename ... Ts>
void write(T arg, Ts ... args) {write(arg);if(sizeof...(args) != 0) {putchar(' ');write(args ...);}}
using namespace std;

ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a % b);
}

ll lcm(ll a, ll b) {
    return a / gcd(a, b) * b;
}

const int N = 1e5 + 5;
const ll R = 1e9;
int n, tot = 0, root;
ll input[N];
int lc[N << 4] , rc[N << 4], val[N << 4];
int l[N] , r[N];
int query (int rt, ll l, ll r, ll tl , ll tr)
{
    int ans = 0;
    if (tl >= l && tr <= r)
        return val[rt];
    ll mid = (tl + tr) >> 1;
    if (l <= mid) ans += query (lc[rt], l , r, tl , mid);
    if (r > mid ) ans += query (rc[rt] ,l , r, mid + 1, tr);
    return ans;
}
void insert (int &rt, ll l , ll r ,ll k)
{
    if (!rt)
        rt = ++ tot;
    if (l == r)
    {
        val[rt] += 1;
        return ;
    }
    ll mid = (l + r) >> 1;
    if (k <= mid) insert (lc[rt] , l , mid , k);
    else insert (rc[rt], mid + 1, r, k);
    val[rt] = val[lc[rt]] + val[rc[rt]];
}

int main (void)
{
    read (n);
    for (int i = 1 ; i <= n ; i ++)
    {
        read (input[i]);
        l[i] = query (root , 0 , input[i] - 1 , 0, R);
        insert (root, 0 , R , input[i]);
    }

    mem(lc ,0 ) , mem(rc, 0) , mem(val, 0) , root = tot = 0;

    for (int i = n ; i >= 1 ; i --)
    {
        r[i] = query (root , input[i] + 1, R , 0, R);
        insert (root, 0 , R , input[i]);
    }

    ll ans = 0;
    for (int i = 1 ; i <= n ; i ++)
        ans += l[i] * r[i];
    write (ans), LF;
}


  • 扫描线
  • 经典求面积,注意线段树叶子节点存的实际是线段(区间长度为2)
  • 经典例题:P5490
    1.非离散化版本
//#define LOCAL
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define mem(a, b) memset(a,b,sizeof(a))
#define sz(a) (int)a.size()
#define INF 0x3f3f3f3f
#define DNF 0x7f
#define DBG printf("this is a input\n")
#define fi first
#define se second
#define mk(a, b) make_pair(a,b)
#define pb push_back
#define LF putchar('\n')
#define SP putchar(' ')
#define p_queue priority_queue
#define CLOSE ios::sync_with_stdio(0); cin.tie(0)

template<typename T>
void read(T &x) {x = 0;char ch = getchar();ll f = 1;while(!isdigit(ch)){if(ch == '-')f *= -1;ch = getchar();}while(isdigit(ch)){x = x * 10 + ch - 48; ch = getchar();}x *= f;}
template<typename T, typename... Args>
void read(T &first, Args& ... args) {read(first);read(args...);}
template<typename T>
void write(T arg) {T x = arg;if(x < 0) {putchar('-'); x =- x;}if(x > 9) {write(x / 10);}putchar(x % 10 + '0');}
template<typename T, typename ... Ts>
void write(T arg, Ts ... args) {write(arg);if(sizeof...(args) != 0) {putchar(' ');write(args ...);}}
using namespace std;

ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a % b);
}

ll lcm(ll a, ll b) {
    return a / gcd(a, b) * b;
}

int n ;
const int N = 1e6 + 5;
ll x[N];
struct point{
    int l, r, h;
    int k;
    bool operator < (const point& po) const {
        return h < po.h;
    }
}line[N];
struct node {
    int l , r;
    int mark;
    ll len;
}tree[N << 4];
void pushup(int i)
{
    int l = tree[i].l , r = tree[i].r;
    if (tree[i].mark)
        tree[i].len = x[r + 1] - x[l];
    else
        tree[i].len = tree[i<<1].len + tree[i<<1|1].len;
}
void build (int i , int l , int r)
{
    tree[i].l = l , tree[i].r = r;
    tree[i].len = tree[i].mark = 0;
    if (l == r) return ;
    int mid = (l + r) >> 1;
    build (i << 1 , l , mid);
    build (i << 1 | 1, mid + 1, r);
}
void update (int i , ll l, ll r, int k)
{
    int tl = tree[i].l , tr = tree[i].r;

    if(x[tr + 1] <= l || r <= x[tl])
        return;

    if (l <= x[tl] && r >= x[tr + 1])
    {
        tree[i].mark += k;
        pushup(i);
        return ;
    }


    update (i << 1 , l , r, k);
    update (i << 1 | 1 , l, r, k);
    pushup(i);
}
int main (void)
{
    read (n);
    for (int i = 1 ; i <= n ; i ++)
    {
        int x1, y1, x2, y2;
        read (x1, y1, x2, y2);
        x[2 * i - 1] = x1 , x[2 * i] = x2;
        line[2 * i - 1] = {x1, x2, y1, 1};
        line[2 * i] = {x1, x2, y2, -1};
    }
    n <<= 1;
    sort (line + 1 , line + 1 + n);
    sort (x + 1, x + 1 + n);

    int tot = unique (x + 1, x + 1 + n) - x - 1;
    build (1, 1, tot-1);
    ll ans = 0;
    for (int i = 1 ; i < n ; i ++)
    {
        update (1, line[i].l, line[i].r , line[i].k);
        //cout << tree[1].len << ' ' << line[i+1].h - line[i].h << endl;
        ans += tree[1].len * (line[i+1].h - line[i].h);
    }
    cout << ans << endl;
}

2.离散化版本

//#define LOCAL
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define mem(a, b) memset(a,b,sizeof(a))
#define sz(a) (int)a.size()
#define INF 0x3f3f3f3f
#define DNF 0x7f
#define DBG printf("this is a input\n")
#define fi first
#define se second
#define mk(a, b) make_pair(a,b)
#define pb push_back
#define LF putchar('\n')
#define SP putchar(' ')
#define p_queue priority_queue
#define CLOSE ios::sync_with_stdio(0); cin.tie(0)

template<typename T>
void read(T &x) {x = 0;char ch = getchar();ll f = 1;while(!isdigit(ch)){if(ch == '-')f *= -1;ch = getchar();}while(isdigit(ch)){x = x * 10 + ch - 48; ch = getchar();}x *= f;}
template<typename T, typename... Args>
void read(T &first, Args& ... args) {read(first);read(args...);}
template<typename T>
void write(T arg) {T x = arg;if(x < 0) {putchar('-'); x =- x;}if(x > 9) {write(x / 10);}putchar(x % 10 + '0');}
template<typename T, typename ... Ts>
void write(T arg, Ts ... args) {write(arg);if(sizeof...(args) != 0) {putchar(' ');write(args ...);}}
using namespace std;

ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a % b);
}

ll lcm(ll a, ll b) {
    return a / gcd(a, b) * b;
}

int n ;
const int N = 1e6 + 5;
ll x[N];
struct point{
    int l, r, h;
    int k;
    bool operator < (const point& po) const {
        return h < po.h;
    }
}line[N];
struct node {
    int l , r;
    int mark;
    ll len;
}tree[N << 4];
void pushup(int i)
{
    int l = tree[i].l , r = tree[i].r;
    if (tree[i].mark)
        tree[i].len = x[r + 1] - x[l];
    else
        tree[i].len = tree[i<<1].len + tree[i<<1|1].len;
}
void build (int i , int l , int r)
{
    tree[i].l = l , tree[i].r = r;
    tree[i].len = tree[i].mark = 0;
    if (l == r) return ;
    int mid = (l + r) >> 1;
    build (i << 1 , l , mid);
    build (i << 1 | 1, mid + 1, r);
}
void update (int i , ll l, ll r, int k)
{
    int tl = tree[i].l , tr = tree[i].r;
    if (l <= tl && r >= tr)
    {
        tree[i].mark += k;
        pushup(i);
        return ;
    }
    int mid = (tl + tr) / 2 ;
    if (l <= mid) update (i << 1 , l , r, k);
    if (r >  mid) update (i << 1|1 , l, r, k);
    pushup(i);
}
int main (void)
{
    read (n);
    for (int i = 1 ; i <= n ; i ++)
    {
        int x1, y1, x2, y2;
        read (x1, y1, x2, y2);
        x[2 * i - 1] = x1 , x[2 * i] = x2;
        line[2 * i - 1] = {x1, x2, y1, 1};
        line[2 * i] = {x1, x2, y2, -1};
    }
    n <<= 1;
    sort (line + 1 , line + 1 + n);
    sort (x + 1, x + 1 + n);

    int tot = unique (x + 1, x + 1 + n) - x - 1;
    build (1, 1, tot-1);

    ll ans = 0;
    for (int i = 1 ; i < n ; i ++)
    {
        int xl = lower_bound(x+1,x+tot+1,line[i].l) - x;
        int xr = lower_bound(x+1,x+tot+1,line[i].r) - x - 1;
        update (1, xl, xr , line[i].k);
        //cout << tree[1].len << ' ' << line[i+1].h - line[i].h << endl;
        ans += tree[1].len * (line[i+1].h - line[i].h);
    }
    cout << ans << endl;
}

  • 经典扫描线求周长(注意sort和cmp)
//#define LOCAL
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define mem(a, b) memset(a,b,sizeof(a))
#define sz(a) (int)a.size()
#define INF 0x3f3f3f3f
#define DNF 0x7f
#define DBG printf("this is a input\n")
#define fi first
#define se second
#define mk(a, b) make_pair(a,b)
#define pb push_back
#define LF putchar('\n')
#define SP putchar(' ')
#define p_queue priority_queue
#define CLOSE ios::sync_with_stdio(0); cin.tie(0)

template<typename T>
void read(T &x) {x = 0;char ch = getchar();ll f = 1;while(!isdigit(ch)){if(ch == '-')f *= -1;ch = getchar();}while(isdigit(ch)){x = x * 10 + ch - 48; ch = getchar();}x *= f;}
template<typename T, typename... Args>
void read(T &first, Args& ... args) {read(first);read(args...);}
template<typename T>
void write(T arg) {T x = arg;if(x < 0) {putchar('-'); x =- x;}if(x > 9) {write(x / 10);}putchar(x % 10 + '0');}
template<typename T, typename ... Ts>
void write(T arg, Ts ... args) {write(arg);if(sizeof...(args) != 0) {putchar(' ');write(args ...);}}
using namespace std;

ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a % b);
}

ll lcm(ll a, ll b) {
    return a / gcd(a, b) * b;
}

const int N = 20005;
int n , x[N] , y[N];
struct node {
    int l , r;
    int mark;
    ll len;
}tr[N << 4][5];
struct li
{
    int l , r , h, k;
    bool operator < (const li& no) const {
        return h == no.h ? k > no.k : h < no.h;
    }
}linex[N], liney[N];

void pushup(int i, int k)
{
    int l = tr[i][k].l , r = tr[i][k].r;
    if (k == 0)
    {
        if (tr[i][k].mark)
            tr[i][k].len = x[r + 1] - x[l];
        else
            tr[i][k].len = tr[i<<1][k].len + tr[i<<1|1][k].len;
    }
    else
    {
        if (tr[i][k].mark)
            tr[i][k].len = y[r + 1] - y[l];
        else
            tr[i][k].len = tr[i<<1][k].len + tr[i<<1|1][k].len;
    }
}


void build (int k, int i , int l , int r)
{
    tr[i][k].l = l , tr[i][k].r = r;
    tr[i][k].len = tr[i][k].mark = 0;
    if (l == r) return ;
    int mid = (l + r) >> 1;
    build (k ,i << 1 , l , mid);
    build (k ,i << 1 | 1, mid + 1, r);
}

void update (int id, int i , int l, int r, int k)
{
    int tl = tr[i][id].l , trr = tr[i][id].r;
    if (l <= tl && r >= trr)
    {
        tr[i][id].mark += k;
        pushup(i, id);
        return ;
    }
    int mid = (tl + trr) >> 1 ;
    if (l <= mid) update (id, i << 1 , l , r, k);
    if (r >  mid) update (id, i << 1 | 1 , l, r, k);
    pushup(i, id);
}
int main (void)
{
    read (n);
    for (int i = 1 ; i <= n ; i ++)
    {
        int x1, y1, x2, y2;
        read (x1, y1, x2, y2);
        linex[i * 2 - 1] = {x1, x2, y1, 1};
        linex[i * 2] = {x1, x2, y2, -1};
        liney[i * 2 - 1] = {y1, y2, x1, 1};
        liney[i * 2] = {y1, y2, x2, -1};
        x[i * 2 - 1] = x1 , x[i * 2] = x2;
        y[i * 2 - 1] = y1 , y[i * 2] = y2;
    }

    n <<= 1;

    sort (linex + 1 , linex + 1 + n);
    sort (liney + 1,  liney + 1 + n);

    sort (x + 1, x + 1 + n);
    sort (y + 1 , y + 1 + n);

    int totx = unique (x + 1 , x + 1 + n) - x - 1;
    int toty = unique (y + 1 , y + 1 + n) - y - 1;

    build (0, 1, 1, totx - 1);
    build (1, 1, 1, toty - 1);

    ll ans = 0;

    int last = 0;
    for (int i = 1 ; i <= n ; i ++)
    {
        int xl = lower_bound(x + 1, x + 1 + totx, linex[i].l) - x;
        int xr = lower_bound(x + 1, x + 1 + totx, linex[i].r) - x - 1;
        update(0, 1, xl, xr, linex[i].k);
        ans += abs(tr[1][0].len - last) , last = tr[1][0].len;
    }


    //cout << ans << endl;
    last = 0;
    for (int i = 1 ; i <= n ; i ++)
    {
        int yl = lower_bound(y + 1 , y + 1 + toty, liney[i].l) - y;
        int yr = lower_bound(y + 1,  y + 1 + toty, liney[i].r) - y - 1;
        update (1 , 1, yl ,yr, liney[i].k);
        ans += abs(tr[1][1].len - last), last = tr[1][1].len;
    }

    cout << ans << endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值