Los greedy continent Valley P2184--

Portal: QAQQAQ

 

Question is intended: to a length of n-$ $ interval, may be every two operations:

1. Place a bomb and in the different types of previously $ [l, r] $ in this interval

2. Query in $ [l, r] $ interval how many different kinds of bombs

 

Ideas: first reaction is to segment tree: But what has been thought out to maintain the tree line

with? And may be due to a bomb covered interval length is changed, not the kind of change because of the bomb.

The maximum? Probably two completely disjoint interval there are two different kinds of bombs

 

So we want to change an idea thought: We can be converted to this topic: to give you a range, before seeking those intervals and the interval intersects a few

Think: two intervals intersecting What are the characteristics of it? Two intervals are away from what characteristic? - either from the two-phase range $ l1> r2 $, either $ r1 <l2 $

The number of times we have established two tree line are maintained within the range of $ l, r $ are presented: we can easily find the idea

Then, for each query $ l, r $, query the $ [1, l-1] $ interval $ $ R & lt Several (cnt1), the $ [r + 1, n] $ $ L $ query has several (cnt2), then the total number of the previous section by subtracting ($ cnt1 + cnt2 $) can.

(Much like the idea of ​​CF1190D, maintaining the position of the number of points of presence, the general this question should use discrete (inexplicably thought CDQ partition ......))

 

Code :( segment tree Sure, but Fenwick tree seems more convenient)

#include<bits/stdc++.h>
using namespace std;
const int N=100050;

int sum[2][N*4],n,m;//0:l 1:r
void build(int x,int l,int r)
{
    if(l==r) 
    {
        sum[1][x]=0;
        sum[0][x]=0;
        return;
    }
    int mid=(l+r)>>1;
    build(x+x,l,mid);
    build(x+x+1,mid+1,r);
}

void update ( you get, you're the, you're down, you pos, you're in)
{
    if(l==r) 
    {
        sum[bl][x]++;
        return;
    }
    int mid=(l+r)>>1;
    if(mid>=pos) update(x+x,l,mid,pos,bl);
    else update(x+x+1,mid+1,r,pos,bl);
    sum[bl][x]=sum[bl][x+x]+sum[bl][x+x+1];
}

you query ( you get, you're the, you're down, you L, you R, you're in)
{
    int ret=0;
    if(L>R) return 0;
    if(L<=l&&r<=R) return sum[bl][x];
    int mid=(l+r)>>1; 
    if(mid>=L) ret+=query(x+x,l,mid,L,R,bl);
    if(mid<R) ret+=query(x+x+1,mid+1,r,L,R,bl);
    return ret;
}

int main ()
{
    int sum=0;
    scanf("%d%d",&n,&m);
    while(m--)
    {
        int x,y,opt;
        scanf("%d%d%d",&opt,&x,&y);
        if(opt==1)
        {
            update(1,1,n,x,0);
            update(1,1,n,y,1);
            sum++;
        }
        else
        {
            int now=0;
            now+=query(1,1,n,y+1,n,0);
            now+=query(1,1,n,1,x-1,1);
            printf("%d\n",sum-now);
        }
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/Forever-666/p/11306355.html