題解有誤,並非所有與線段樹節點[l,r]相交的所有區間[s.t]都要存入vector
插入區間[s,t]時,我們覆蓋了一段完整的區間,如圖
實質上是覆蓋了表面的一層,即標記不下傳
故我們merge時要考慮每一層的vector
插入時,如果兩個區間恰好相接,也視作互相到達,所以合併時用(s,t)合併,插入時用[s+1,t-1]插入
由於區間按長度從小到大插入,故不存在這樣的情況:
故merge的區間一定是兩兩可達的,用並查集來維護這種關係
最後,若區間存在包含關係,則a可以到達b,b不能到達a(一端端點重合也算),則特判即可,由於端點可能重合,故不能只判斷乙個端點
**非常簡單:
#includeusing namespace std;
#define go(i,a,b) for(int i=a;i<=b;++i)
#define com(i,a,b) for(int i=a;i>=b;--i)
#define mem(a,b) memset(a,b,sizeof(a))
#define ls rt<<1
#define rs rt<<1|1
const int inf=0x3f3f3f3f,n=2e5+10;
int n,m,op[n],a[n],b[n],c[n],d[n],f[n],rk[n],id,tot;
vectorinter[n<<2];
void read(int &x)
while(isdigit(c))
x*=f;
}inline int find(int x)
void merge(int rt,int l,int r,int k)
void insert(int rt,int l,int r,int x,int y,int k)
int mid=l+r>>1;
if(x<=mid) insert(ls,l,mid,x,y,k);
if(y>mid) insert(rs,mid+1,r,x,y,k);
}int main()
sort(rk+1,rk+tot+1);
tot=unique(rk+1,rk+tot+1)-rk-1;
go(i,1,n) if(op[i]==1)
int x,y;
go(i,1,n)
else
} }return 0;
}
高手訓練 線段樹 棧的維護
time limit 20 sec memory limit 512 mb 從前有個棧,一開始是空的。你寫下了 m 個操作,每個操作形如 k v 若 k 0,代表往棧頂加入乙個數 v 若 k 1,則代表從棧頂彈出 v 個數,如果棧中的元素少於 v 個,則全部彈出。接著你又進行了 q 次修改,每次你會...
T1082 線段樹練習3 codevs
題目描述 description 給你n個數,有兩種操作 1 給區間 a,b 的所有數增加x 2 詢問區間 a,b 的數的和。輸入描述 input description 第一行乙個正整數n,接下來n行n個整數,再接下來乙個正整數q,每行表示操作的個數,如果第乙個數是1,後接3個正整數,表示在區間 ...
WC模擬(1 12) T3 小C的線段樹
小c的線段樹 題目背景 1.12 wc 模擬t3 分析 dp 據說,這個玩意兒才是本場 t1 考場上只想到乙個 nm2的暴力,就是,直接定義 f i l r 表示當前是第 i個區間,上乙個括號是 l,r 這樣過掉了 k 1 的部分。考慮標算,注意到當 n m 時,是不存在合法操作序列的,所以因為 n...