hdu 4614 Vases and Flowers

來源:互聯網
上載者:User

周末UA做了這場多校的vjudge版本。

我去陪爸媽去山溝溝轉了,回來聽說有個這個線段樹,想敲敲。

多年不做線段樹,好噁心><

struct Tnode{// 一維線段樹     int l,r;    int cover;    int lid, rid;    int sum;    int len() { return r - l;}    int mid() { return MID(l,r);}    bool in(int ll,int rr) { return l >= ll && r <= rr; }    void lr(int ll,int rr){ l = ll; r = rr;}};

這個是我每次都用的線段樹定義,根據題目不同,會更改一些標記。

根據這個題來說,cover = 0表示該區間的位置都為空白,cover=1表示該區間都不為空白,cover=-1表示部分為空白(借鑒於zoj線段覆蓋那道題)

sum表示該區間裡為空白的位置長度和。

lid表示該區間最左邊為空白的位置號,rid為最右邊為空白的位置號。若sum = 0,則lid rid都為-1。


操作1:

輸入a ,b

比較麻煩,求左端點很簡單,直接查詢下就行了。求出左端點lpos。若為-1輸出Can not balabala。。

求右端點的時候我是先求出0~lpos中間的空位置val,然後求從0~n-1中空位置大於等於val+b的位置。方便分。

因為糾結一點,不知道如何在區間[l,r]中尋找空位置為d的位置(就我目前維護的標記來說),但是尋找[0,r]的位置會很easy~懂吧?


操作2:

求個sum即可


出錯地方:查左端點的時候,如果左邊查不到,那麼右邊得查,我直接左邊差不到就返回了。要知道如果[l,r]區間中有sum>0的位置,但是空位置不一定是在需要的區間中。

比如區間[0, 9]中有空位置[0,1]和[5,6],但是呢,我需要的是[3, 6]中的空位置,顯然mid後,左邊[0,5]有空位置,但是是找不到對應的在[3,6]的空位置的。改過就過了。


時間:C++,400+MS,估計是用指標了,慢了,但是真心不習慣用數組替代,唉唉唉。 


#include <set>#include <map>#include <queue>#include <stack>#include <math.h>#include <stdio.h>#include <stdlib.h>#include <iostream>#include <limits.h>#include <string.h>#include <string>#include <algorithm>#define MID(x,y) ( ( x + y ) >> 1 )#define L(x) ( x << 1 )#define R(x) ( x << 1 | 1 )#define FOR(i,s,t) for(int i=(s); i<(t); i++)#define FORD(i,s,t) for(int i=(s-1); i>=t; i--)#define BUG puts("here!!!")#define STOP system("pause")#define file_r(x) freopen(x, "r", stdin)#define file_w(x) freopen(x, "w", stdout)using namespace std;const int MAX = 50010;struct Tnode{// 一維線段樹     int l,r;    int cover;    int lid, rid;    int sum;    int len() { return r - l;}    int mid() { return MID(l,r);}    bool in(int ll,int rr) { return l >= ll && r <= rr; }    void lr(int ll,int rr){ l = ll; r = rr;}};Tnode node[MAX<<2];void Update_sum(int t){node[t].sum = node[R(t)].sum + node[L(t)].sum;if( node[L(t)].lid != -1 )node[t].lid = node[L(t)].lid;elsenode[t].lid = node[R(t)].lid;node[t].rid = max(node[L(t)].rid, node[R(t)].rid);if( node[t].sum == 0 )node[t].cover = 1;elseif( node[t].sum == node[t].len() )node[t].cover = 0;elsenode[t].cover = -1;}void Build(int t,int l,int r){node[t].lr(l,r);node[t].lid = l;node[t].rid = r;node[t].sum = node[t].len();node[t].cover = 0;if( node[t].len() == 1 )return ;int mid = MID(l,r);Build(L(t),l,mid);Build(R(t),mid,r);}void update_cover(int t) {if( node[t].cover == -1 )return ;if( node[t].cover == 1 ) {node[t].sum = 0;node[t].lid = -1;node[t].rid = -1;} else {node[t].sum = node[t].len();node[t].lid = node[t].l;node[t].rid = node[t].r;}}void push_cover(int t) {if( node[t].len() == 1 ) return ;if( node[t].cover != -1 ) {node[L(t)].cover = node[R(t)].cover = node[t].cover;update_cover(L(t));update_cover(R(t));}}void Update(int t,int l,int r,int val){push_cover(t);if( node[t].in(l,r) ){node[t].cover = val;update_cover(t);return ;}if( node[t].len() == 1 ) return ;int mid = node[t].mid();if( l < mid ) Update(L(t),l,r,val);if( r > mid ) Update(R(t),l,r,val);Update_sum(t);}int Query(int t,int l,int r){push_cover(t);if( node[t].in(l,r) )return node[t].sum;if( node[t].len() == 1 ) return 0;int mid = node[t].mid();int ans = 0;if( l < mid ) ans += Query(L(t),l,r);if( r > mid ) ans += Query(R(t),l,r);return ans;}int Querylid(int t,int l,int r){push_cover(t);if( node[t].in(l,r) && node[t].sum > 0 )return node[t].lid;if( node[t].len() == 1 ) return -1;int mid = node[t].mid();if( l < mid && node[L(t)].sum > 0 ) {int pos = Querylid(L(t),l,r);if( pos != -1 )return pos;}if( r > mid && node[R(t)].sum > 0 )return Querylid(R(t),l,r);return -1;}int Queryrid(int t,int l, int r, int val){push_cover(t);if( node[t].sum <= val )return node[t].rid;if( node[t].len() == 1 ) return -1;int mid = node[t].mid();if( l < mid && node[L(t)].sum >= val )return Queryrid(L(t), l, r, val);if( r > mid && node[R(t)].sum > 0 )return Queryrid(R(t), l, r, val - node[L(t)].sum);return -1;}int main() {int ncases, n, m;int opera, a, b;scanf("%d", &ncases);while( ncases-- ) {scanf("%d%d", &n, &m);if( m > 0 ) Build(1, 0, n);while( m-- ) {scanf("%d%d%d", &opera, &a, &b);if( opera == 1 ) {int lpos = Querylid(1, a, n);if( lpos == -1 ) {puts("Can not put any one.");continue;}int val = Query(1, 0, lpos);int rpos = Queryrid(1, 0, n, b + val);printf("%d %d\n", lpos, rpos-1);Update(1, lpos, rpos, 1);}if( opera == 2 ) {if( b > n )b = n - 1;int ans = Query(1, a, b+1);Update(1, a, b+1, 0);printf("%d\n", b - a + 1 - ans);}}puts("");}return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.