注意懒操作更新时要考虑周全,比如在push_down不是赋值而是叠加,因为可能push_down时下面会有没有来得及push_down的线段,会导致错误
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#define MAX 1000007
using namespace std;
int t,n,l,r,k;
struct Node
{
int l,r,maxn,lazy;
}tree[MAX<<2];
void build ( int u , int l , int r )
{
tree[u].l = l , tree[u].r = r;
tree[u].maxn = 0;
tree[u].lazy = 0;
if ( l == r ) return;
int mid = l + r >> 1;
build ( u<<1 , l , mid );
build ( u<<1|1 , mid+1 , r );
}
void push_up ( int u )
{
tree[u].maxn = max ( tree[u<<1].maxn , tree[u<<1|1].maxn );
}
void push_down ( int u )
{
int lazy = tree[u].lazy;
if ( lazy )
{
tree[u<<1].lazy += lazy;
tree[u<<1|1].lazy += lazy;
tree[u].lazy = 0;
tree[u<<1].maxn += lazy;
tree[u<<1|1].maxn += lazy;
}
}
void update ( int u , int left , int right )
{
int l = tree[u].l , r = tree[u].r;
if ( left <= l && r <= right )
{
tree[u].maxn++;
tree[u].lazy++;
return;
}
int mid = l + r >> 1;
push_down ( u );
if ( left <= mid && right >= l )
update ( u<<1 , left , right );
if ( left <= r && right > mid )
update ( u<<1|1 , left , right );
push_up ( u );
}
int query ( int u , int left , int right )
{
int l = tree[u].l , r = tree[u].r;
if ( left <= l && r <= right )
return tree[u].maxn;
push_down ( u );
int mid = l + r >> 1;
int ret = 0;
if ( left <= mid && right >= l )
ret = max ( ret , query ( u<<1 , left , right ) );
if ( left <= r && right > mid )
ret = max ( ret , query ( u<<1|1 , left , right ) );
return ret;
}
int main ( )
{
scanf ( "%d" , &t );
int c = 1;
while ( t-- )
{
scanf ( "%d%d" , &k , &n );
build ( 1 , 1 , MAX-2 );
vector<int> v;
for ( int i = 1 ; i <= n ; i++ )
{
scanf ( "%d%d" , &l , &r );
r--;
if ( query ( 1 , l , r ) < k )
{
v.push_back ( i );
update ( 1 , l , r );
}
}
int len = v.size();
printf ( "Case %d:\n" , c++ );
if ( len > 0 )
{
for ( int i = 0 ; i < len ; i++ )
printf ( "%d " , v[i] );
puts ( "" );
}
puts ( "" );
}
}