Topic link: http://poj.org/problem?id=2528
Solution: large scope, few points, consider discretization
1. Discretization maps 20,000 points of 1-10,000,000 to 1-20,000
The concrete steps are: counting all points - > sorting - > de-duplication - > mapping one by one.
The dis array is 1000w open, and the type is unsigned short (16 bits, enough size, and more space-saving)
for (int i = 0;i<n;i++){ scanf("%d %d",&l[i],&r[i]); mp[cnt++] = l[i]; mp[cnt++] = r[i]; } sort(mp,mp+cnt); cnt = unique(mp,mp+cnt)-mp; for (int i=0;i<cnt;i++) dis[mp[i]] = i+1;
2. Put the discrete intervals one by one into the segment tree for updating. The segment tree maintains the color of the segment. If tree[i]=-1 indicates that the segment has multiple colors, tree[i]=0 means no color.
There are probably tree arrays themselves as lazy arrays.
(2) push_up() is used to feedback the current node after the update of the child node, to ensure the correct value of the current node.
void push_up(int rt) { if (tree[rt<<1]==-1 || tree[rt<<1|1]==-1) tree[rt] = -1; else { if (tree[rt<<1]==0) tree[rt] = tree[rt<<1|1]; else if (tree[rt<<1|1]==0) tree[rt] = tree[rt<<1]; else if (tree[rt<<1|1]!=tree[rt<<1]) tree[rt] = -1; } } void update(int L,int R,int x,int rt,int l,int r) { //printf("rt=%d [%d,%d]\n",rt,l,r); if (L<=l && r<=R){ tree[rt] = x; return ; } if (tree[rt]>0) tree[rt<<1] = tree[rt<<1|1] = tree[rt]; mid; if (L<=m) update(L,R,x,lson); if (R>m) update(L,R,x,rson); push_up(rt); }
3. dfs traverse the whole tree
When tree [rt]= - 1, the color of the child node is different, two child nodes are searched.
When tree[rt] = 0, the maintenance interval has no color, return directly
When tree [rt] > 0, there is a color. If the current color is not accessed, enter the answer and mark the access.
void dfs(int rt,int l,int r) { //printf("tree=%d,[%d,%d]\n",tree[rt],l,r); if (tree[rt]>0){ if (!vis[tree[rt]]) ans++; vis[tree[rt]] = true; return ; } if (!tree[rt]) return ; mid; if (tree[rt]==-1){ dfs(lson); dfs(rson); } }
Complete code:
#include<cstdio> #include<algorithm> #include<map> #include<cstring> #define lson rt<<1,l,m #define rson rt<<1|1,m+1,r #define mid int m = l+r>>1 #define debug(x) printf("Line %s----\n",#x) using namespace std; const int N = 2e4+5; int tree[N<<2],ans; bool vis[N]; int mp[N],l[N],r[N]; unsigned short dis[10000000+5]; void push_up(int rt) { if (tree[rt<<1]==-1 || tree[rt<<1|1]==-1) tree[rt] = -1; else { if (tree[rt<<1]==0) tree[rt] = tree[rt<<1|1]; else if (tree[rt<<1|1]==0) tree[rt] = tree[rt<<1]; else if (tree[rt<<1|1]!=tree[rt<<1]) tree[rt] = -1; } } void update(int L,int R,int x,int rt,int l,int r) { //printf("rt=%d [%d,%d]\n",rt,l,r); if (L<=l && r<=R){ tree[rt] = x; return ; } if (tree[rt]>0) tree[rt<<1] = tree[rt<<1|1] = tree[rt]; mid; if (L<=m) update(L,R,x,lson); if (R>m) update(L,R,x,rson); push_up(rt); } void dfs(int rt,int l,int r) { //printf("tree=%d,[%d,%d]\n",tree[rt],l,r); if (tree[rt]>0){ if (!vis[tree[rt]]) ans++; vis[tree[rt]] = true; return ; } if (!tree[rt]) return ; mid; if (tree[rt]==-1){ dfs(lson); dfs(rson); } } int main() { int t; scanf("%d",&t); while (t--){ memset(tree,0,sizeof tree); memset(vis,0,sizeof vis); int n,cnt=0; scanf("%d",&n); for (int i = 0;i<n;i++){ scanf("%d %d",&l[i],&r[i]); mp[cnt++] = l[i]; mp[cnt++] = r[i]; } sort(mp,mp+cnt); cnt = unique(mp,mp+cnt)-mp; for (int i=0;i<cnt;i++) dis[mp[i]] = i+1; for (int i = 0;i<n;i++){ l[i] = dis[l[i]]; r[i] = dis[r[i]]; update(l[i],r[i],i+1,1,1,cnt); } ans = 0; dfs(1,1,cnt); printf("%d\n",ans); } return 0; }