最大流dicnic裸題 hdu1532 Summer III
阿新 • • 發佈:2019-01-07
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int casenum,postnum,ans,cnt,temp; const int maxn=40000; int vis[maxn]; int m[maxn][2]; struct Tree{ int l; int r; int n;///n統計顏色 }tree[maxn]; struct Dis{ int interval;///interval記錄原來區間的邊,num記錄位置(方便區間對應) int num; }dis[maxn]; bool cmp1(const Dis &a,const Dis &b) { return a.interval<b.interval; } void init(int node,int l,int r) { tree[node].l=l; tree[node].r=r; tree[node].n=0; if(l!=r) { int mid=(l+r)>>1;///除2是>>1,乘2是>>1;=(tree[node].切忌寫成l+tree[node].r)>>1,是當前的中點 init(2*node,l,mid); init(2*node+1,mid+1,r); } } void color(int col,int l,int r,int node) { if(tree[node].l==l&&tree[node].r==r) { tree[node].n=col;///找到了區間,更新這個區間的顏色 return ; } int mid=(tree[node].l+tree[node].r)>>1; if(tree[node].n>0))///重點注意,如果這個區間被訪問了,並且這個區間有顏色,就要將這個區間的顏色更新到其左右孩子的節點,並且要將這個區間的顏色清空,這樣才能算是覆蓋 {///區間被訪問是指其區間的起點和終點被訪問,所以中間的要清空 { tree[node*2].n=tree[node*2+1].n=tree[node].n; tree[node].n=0; } if(tree[2*node+1].l<=l)///注意這裡是區間子節點去匹配 color(col,l,r,2*node+1); else if(tree[2*node].r>=r) color(col,l,r,2*node);///同上 else { color(col,l,mid,2*node); color(col,mid+1,r,2*node+1); } } void solve(int node) { if(tree[node].n)///如果這個區間有顏色了,停止訪問並返回,因為下面的無論有沒有顏色都是已經被覆蓋的 { if(!vis[tree[node].n])///如果有顏色且沒被統計過的,就統計一次 { ans++; vis[tree[node].n]=1; } return; } solve(2*node); solve(2*node+1); return; } int main() { scanf("%d",&casenum); while(casenum--) { ans=0; cnt=0; scanf("%d",&postnum); for(int i=0;i<postnum;i++) { scanf("%d%d",&m[i][0],&m[i][1]); dis[2*i].interval=m[i][0];///這裡直接陣列相鄰的兩個位置記錄區間值,而不用二維陣列,方便後面遍歷,也減少複雜度。 dis[2*i+1].interval=m[i][1]; dis[2*i].num=-(i+1); dis[2*i+1].num=i+1; } sort(dis,dis+2*postnum,cmp1); temp=dis[0].interval; cnt=1;///座標從1開始 ///離散化!!!!!! for(int i=0;i<2*postnum;i++) { if(temp!=dis[i].interval) { cnt++;///如果和前面的不同,這迭代加1 temp=dis[i].interval; } if(dis[i].num>0) { m[dis[i].num-1][1]=cnt;///如map[0][0],map[0][1]分別代表排序後第一個張貼海報的左右區間,其中的數值為離散化後數軸的座標 } else { m[-dis[i].num-1][0]=cnt;///cnt為其離散化後所在數軸的座標 } } memset(tree,0,sizeof(tree)); memset(vis,0,sizeof(vis)); init(1,1,cnt);///一開始debug好久都沒找到問題所在,原來位置引數的位置寫錯了 for(int i=0;i<postnum;i++) { color(1+i,m[i][0],m[i][1],1);///每次貼的海報都不一樣(這裡想象著塗色,即每次塗得的顏色不一樣) } solve(1); printf("%d\n",ans); } }