校门外的树(离散化处理)
校门外的树
https://ac.nowcoder.com/acm/problem/16649
如果这题道路长1e9,数组开不下,就可以进行离散化处理:记录每次输入的左右端点,将这些点编号,并按照所在位置大小排序。最后遍历完这些点,统计出没砍掉的区间里有多少树。
左端点的position记为1,右端点记为-1.一段区间没砍掉,当且仅当它左边的左端点个数等于右端点个数
因此可以用一个变量sum来记录,sum=0表明这个点左边的左右端点个数相等。
#include <bits/stdc++.h> using namespace std; int l,m; struct node{ int p;//记录位置,左端点记为1,右端点为-1 //某个树活着,表明当前这点左边l的个数等于r的个数,即sum(p)=0 //若某点既是l又是r,就清0 int a; }n[100001*2]; int comp(struct node x,struct node y){ return x.a<y.a;//x的a小,排在前面 } int main(){ cin >> l >> m; int x,y; for(int i=0;i<m;i++){ cin >> x >> y; n[2*i].a=x; n[2*i].p+=1; n[2*i+1].a=y; n[2*i+1].p-=1; } sort(n,n+2*m,comp);//将区间端点按照位置排序 int cnt=n[0].a;//从0点到最初的点,这之间的树没被砍掉 int sum=n[0].p;//sum记录当前的点是否在被砍的区间内 for(int i=1;i<2*m-1;i++){ if(sum==0) cnt+=n[i].a-n[i-1].a-1; sum+=n[i].p; } cnt+=l-n[2*m-1].a;//最后一个点到终点,这之间的树没被砍掉 cout << cnt << endl; return 0; }