题意
神秘男子的学校安排了$ N $门课,每门从时间$ start_i $上到时间$ end_i$。神秘男子一次只能上一门课。神秘男子想法很多,他想知道$ Q $个时间段$ planstart_j $到$ planend_j $内, 他分别最多上几节课。
对于$100\text{%}$的数据,$1\leq N,Q \leq 10^5,0\leq start_i,end_i,planstart_j,planend_j\leq 10^6$。
思路
对于30%的数据
贪心,将这$N$门课按照结束时间排序,课程能选则选。
预计得分:$30pts$
实际得分:$30pts$
对于60%的数据
对于每一个询问二分出第一节能选的课,预处理类似于链表的结构,处理出每节课结束以后的下一节课。时间复杂度:$O(\sum{ans[j]})$。
预计得分:$60pts$
实际得分:$60pts\text{~}90pts$
对于100%的数据
将算法$2$(即$60pts$)进行优化,构造出类似于森林的结构,倍增预处理一节课后$2^k$节课是什么,询问时想$LCA$处理。时间复杂度:$O(n \log n)$
预计得分:$100pts$
实际得分:$100pts$
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
#include<algorithm> #include<bitset> #include<complex> #include<deque> #include<exception> #include<fstream> #include<functional> #include<iomanip> #include<ios> #include<iosfwd> #include<iostream> #include<istream> #include<iterator> #include<limits> #include<list> #include<locale> #include<map> #include<memory> #include<new> #include<numeric> #include<ostream> #include<queue> #include<set> #include<sstream> #include<stack> #include<stdexcept> #include<streambuf> #include<string> #include<typeinfo> #include<utility> #include<valarray> #include<vector> #include<cctype> #include<cerrno> #include<cfloat> #include<ciso646> #include<climits> #include<clocale> #include<cmath> #include<csetjmp> #include<csignal> #include<cstdarg> #include<cstddef> #include<cstdio> #include<cstdlib> #include<cstring> #include<ctime> using namespace std; #define re register //#define int long long class Quick_Input_Output{ private: static const int S=1<<21; #define tc() (A==B&&(B=(A=Rd)+fread(Rd,1,S,stdin),A==B)?EOF:*A++) char Rd[S],*A,*B; #define pc putchar public: #undef gc #define gc getchar inline int read(){ int res=0,f=1;char ch=gc(); while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=gc();} while(ch>='0'&&ch<='9') res=res*10+ch-'0',ch=gc(); return res*f; } inline void write(int x){ if(x<0) pc('-'),x=-x; if(x<10) pc(x+'0'); else write(x/10),pc(x%10+'0'); } #undef gc #undef pc }I; #define File freopen("course.in","r",stdin);freopen("course.out","w",stdout); int n,q,l,r,mid,top,f[32][100010]; pair<int,int> a[100010]; bool cmp(const pair<int,int> &x,const pair<int,int> &y){ return (x.second<y.second)||(x.second==y.second&&x.first>y.first); } signed main(){ File n=I.read();q=I.read(); for(int i=1;i<=n;i++) a[i].first=I.read(),a[i].second=I.read(); sort(a+1,a+n+1,cmp); for(int i=1;i<=n;i++) if(!top||a[top].first<a[i].first) a[++top]=a[i]; n=top;f[0][n+1]=n+1;a[n+1].second=2e9; for(int i=1;i<=n;i++) f[0][i]=lower_bound(a+1,a+n+1,make_pair(a[i].second+1,0))-a; for(int j=1;j<=16;j++) for(int i=1;i<=n+1;i++) f[j][i]=f[j-1][f[j-1][i]]; for(int i=1;i<=q;i++){ l=I.read();r=I.read(); re int p=lower_bound(a+1,a+n+1,make_pair(l,0))-a,res=0; if(a[p].second<=r) res=1; for(int j=16;j>=0;j--){ if(a[f[j][p]].second<=r){ res+=(1<<j); p=f[j][p]; } } I.write(res);putchar('\n'); } return 0; } |