u:把區間[l,r]覆蓋成1
i:把[-∞,l)(r,∞]覆蓋成0
d:把區間[l,r]覆蓋成0
c:把[-∞,l)(r,∞]覆蓋成0 , 且[l,r]區間0/1互換
s:[l,r]區間0/1互換
cover記錄成段覆蓋,xo記錄互換
當乙個節點得到覆蓋標記時把異或標記清空
當乙個節點得到異或標記的時候,先判斷覆蓋標記,如果是0或1,直接改變一下覆蓋標記,不然的話改變異或標記
開區間閉區間只要數字乘以2就可以處理(偶數表示端點,奇數表示兩端點間的區間)
例: [2,3]=4->6 (2,3)=5->5 [2,3)=4->5
最後用hash查詢一下即可
注意邊界判斷
ps:翻譯了半天才發現題目竟然可以選擇中文.........
#include "stdio.h"
#include "string.h"
#include "math.h"
#include "stdlib.h"
#include "iostream"
#include "algorithm"
using namespace std;
struct comp
sca[300010];
struct comp1
data[300010];
int first;
int hash[300010];
void pushdown(int k)
if (data[k].xo%2!=0) }
void build(int l,int r,int k)
void update_cover(int l,int r,int k,int op)
pushdown(k);
if (r<=data[k].mid) update_cover(l,r,k*2,op);
else
if (l>data[k].mid) update_cover(l,r,k*2+1,op);
else
if (data[k*2].x==data[k*2+1].x && data[k*2].x!=-1) data[k].x=data[k*2].x; else data[k].x=-1;
}void update_xor(int l,int r,int k)
pushdown(k);
if (r<=data[k].mid) update_xor(l,r,k*2);
else
if (l>data[k].mid) update_xor(l,r,k*2+1);
else
if (data[k*2].x==data[k*2+1].x && data[k*2].x!=-1) data[k].x=data[k*2].x; else data[k].x=-1;
}void search(int k)
else
if (data[k].x==0) return ;
else }
int main()
build(0,m*2,1);
for (i=1;i<=n;i++)
if (sca[i].op=='i')
else update_cover(0,m*2,1,0);
} if (sca[i].op=='d')
if (sca[i].op=='c')
else update_cover(0,m*2,1,0);
} if (sca[i].op=='s')
}first=1;
memset(hash,0,sizeof(hash));
search(1);
if (first==1) printf("empty set");
else
else
if (s!=-1)
if (s!=-1)
}}
poj 3225 間隙 橫截面和填充操作
一道題又做了一天。這道題對我來說起初有n多難點。1 區間的開閉怎樣解決。2 如何把區間的交並補 對稱差轉化為對線段樹的操作。後來與實驗室的同學討論了後攻克了前面兩個問題。對於區間的開閉,能夠將區間放大一倍,偶數點表示端點。奇數點表示區間內線段,前開的話左端點加1,右開的話右端點減1。比如 1,3 能...
poj 3485 區間選點
題意 x軸上公路從0到l,x軸上下有一些點給出座標代表村莊,問在公路上最少建幾個出口才能使每個村莊到出口的距離不超過d。以村莊為圓心,半徑為 d 畫圓,與公路相交,得到乙個乙個區間,這麼選點呢?按照區間右端點排序,第乙個點,選擇第一條線段的右端點,當前位置就在這裡,已經 很 靠後了,拿這個點去檢視以...
POJ 2689 區間素數篩,區間移位
給出乙個區間 l,r 求其中相鄰的距離最近和最遠的素數對 其中 1 l r 2,147,483,647,r l 1e6 思路單純打表是不行的,l,r的範圍太大,不能直接求出所有素數。對於int範圍內的合數來說,最小質因子必定小於2 16。所以先用篩法選出50000內的素數即可,因為50000的平方大...