Cattle off the National Day day3 (2018hncpc) E. Grid segment tree

 

Grid

 

This is not quite the same with the usual tree line.

 

This question is to use the segment tree recording section (segment), and then determines the length of all the segments together cover the currently recorded, that is, the line segment may overlap, overlapping calculation interval length can not be repeated, to calculate the actual obtained length of all segments.

 

Think about how record? As usual, I probably, the segment is divided into individual single point, then the section labeled 1, and then, when calculated on to the marked section 1, directly ans + = r-l + 1 , however, because interval segment is dispersed, the search time will be greater than usual. A bit less, I do not know there is no other approach.

However, this question can not practice, because the interval length is 1e9, need discrete.

 

So read the others are doing: the coordinates of discrete points of inquiry arise, then, is the segment [l, r], a segment tree [l, r] value is set to h [r] -h [l], this also I did not want to say focus.

However, after a discrete, mid and mid + 1 value is disconnected, and this way the two values ​​is not continuous intervals not it? Be missing [h [mid], h [mid + 1]] value.

 

Others are doing so read: section segment tree is the left and right subtrees [l, mid] [mid, r], or more accurately, is transmitted to the left and right subtrees discrete array segment is [h [l], h [mid]] and [H [MID], H [r]] , this way we can solve ~ ... yet? Forget that have little detail line interval [val [l], val [ r]] is not true length h [r] -h [l] , when the record r H [r] is the actual value val [r + 1], so as to meet the real length interval (r-l + 1) Well.

 

No want, write it down.

 

Code:

#include<bits/stdc++.h>
#include<tr1/unordered_map>
#define debug printf("!");
using namespace std;
typedef long long ll;
const int maxn=1e5+50;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;

struct P{
    int ly;ll sum;
}tree1[maxn<<3],tree2[maxn<<3];

int h[maxn<<1],tot,nn,mm;
int val(int v)
{
    return lower_bound(h+1,h+1+tot,v)-h;
}


void down(int k,int L,int R,P tree[])
{
    int mid=(L+R)>>1;
    tree[k<<1].sum=h[mid]-h[L];
    tree[k<<1|1].sum=h[R]-h[mid];
    tree[k<<1].ly=1;
    tree[k<<1|1].ly=1;
    tree[k].ly=0;
}

void update(int k,int L,int R,int l,int r,P tree[])
{
    if(l==L&&R==r)
    {
        tree[k].sum=h[r]-h[l];
        tree[k].ly=1;
        return ;
    }
    if(tree[k].ly)down(k,L,R,tree);
    int mid=(L+R)>>1;
    if(r<=mid)update(k<<1,L,mid,l,r,tree);
    else if(l>=mid)update(k<<1|1,mid,R,l,r,tree);
    else
    {
        update(k<<1,L,mid,l,mid,tree);
        update(k<<1|1,mid,R,mid,r,tree);
    }
    tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;
}

struct Q{
    int op,a,b;
}p[maxn];

int main()
{
    ll n,m;
    ll ans,t;
    int q,op,a,b;
    while(~scanf("%lld%lld%d",&n,&m,&q))
    {
        tot=0;
        for(int i=1;i<=q;i++)
        {
            scanf("%d%d%d",&p[i].op,&p[i].a,&p[i].b);
            h[++tot]=p[i].a;h[++tot]=p[i].b+1;
        }
        h[++tot]=n+1;h[++tot]=m+1;
        sort(h+1,h+1+tot);
        tot=unique(h+1,h+1+tot)-h-1;
        nn=val(n+1);mm=val(m+1);
        for(int i=1;i<=tot*4;i++)
        {
            tree1[i].sum=tree1[i].ly=0;
            tree2[i].sum=tree2[i].ly=0;
        }
        for(int i=1;i<=q;i++)
        {
            a=val(p[i].a);b=val(p[i].b+1);
            if(p[i].op==1)update(1,1,nn,a,b,tree1);
            else update(1,1,mm,a,b,tree2);
            ans=(n*m)-(tree1[1].sum*m+tree2[1].sum*n)+(tree1[1].sum*tree2[1].sum);
            if(tree1[1].sum==0)ans+=tree2[1].sum;
            else if(tree2[1].sum==0)ans+=tree1[1].sum;
            else ans++;
            printf("%lld\n" , Year); 
        } 
    } 
}

 

 

but! ! ! However, a better approach is: dynamic prescription segment tree .

 

Guess you like

Origin www.cnblogs.com/kkkek/p/11621399.html