标签:线段树
input | output |
---|---|
3 2 10 2 3 5 7 11 1 2 3 4 5 6 7 8 9 10 11 |
-1 2 2 1 3 3 3 1 1 1 -1 |
#define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 #define LL int const int maxn = 811111; LL ID[maxn<<2];//记录该点属于哪一段 void PushUp(int rt) { if(ID[rt<<1] == ID[rt<<1|1]) ID[rt]=ID[rt<<1]; else ID[rt] = -1; } void PushDown(int rt,int m) { if(ID[rt]!=-1) { ID[rt<<1] = ID[rt]; ID[rt<<1|1] = ID[rt]; } } void build(int l,int r,int rt) { if (l == r) { ID[rt]=-1; return ; } int m = (l + r) >> 1; build(lson); build(rson); PushUp(rt); } void update(int L,int R,int c,int l,int r,int rt) { if (L <= l && r <= R) { ID[rt] = c; return ; } PushDown(rt , r - l + 1); int m = (l + r) >> 1; if (L <= m) update(L , R , c , lson); if (m < R) update(L , R , c , rson); PushUp(rt); } LL query(int L,int R,int l,int r,int rt) { if (L <= l && r <= R) { return ID[rt]; } PushDown(rt , r - l + 1); int m = (l + r) >> 1; LL ret = 0; if (L <= m) ret += query(L , R , lson); if (m < R) ret += query(L , R , rson); return ret; } map<int ,int >my; struct bian { int l,r,len; int id; }; int num[800010];//用来记录输入的所有的数 用于去离散化 bian edge[100010]; int qus[100010];//记录询问 int cmp(bian a,bian b) { return a.len<b.len; } int arr[800010]; int main() { int i,a,b; int t,cas=1; int n; int ji; while(scanf("%d",&n)!=EOF) { my.clear(); ji=0; for(i=0;i<n;i++) { scanf("%d%d",&a,&b); edge[i].l=a; edge[i].r=b; edge[i].len=b-a; edge[i].id=i+1; num[ji++]=a; num[ji++]=b; } int m; scanf("%d",&m); for(i=0;i<m;i++) { scanf("%d",&qus[i]); num[ji++]=qus[i]; } sort(edge,edge+n,cmp); sort(num,num+ji); int ji2=1; for(i=1;i<ji;i++) { if(num[i]!=num[i-1]) num[ji2++]=num[i]; } ji=ji2; for(i=0;i<ji;i++) my[num[i]]=i+1; build(1,ji,1); for(i=n-1;i>=0;i--)//边长从大到小排序, 所以从后往前,边长短的会覆盖掉 { int l=my[edge[i].l]; int r=my[edge[i].r]; update(l,r,edge[i].id,1,ji,1); } for(i=0;i<m;i++) printf("%d\n",query(my[qus[i]],my[qus[i]],1,ji,1)); } return 0; }
标签:线段树
原文地址:http://blog.csdn.net/u013532224/article/details/44263445