我正在尝试SPOJ ACTIV。 (http://www.spoj.com/problems/ACTIV/)我的算法适用于n log n
但仍超出时间限制。请有人帮帮我。
我们应该找到一个人在标记的间隔(开始,结束)中可以进行的非空非重叠活动子集的数量。我首先按开始时间排序。然后我在数组的其余部分结束二进制搜索,同时保持和变量(dp)中的总和
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <algorithm>
#include <utility>
#include <vector>
using namespace std;
typedef pair<long long,long long> p;
vector<long long> ans;
vector<long long> cuml_sum;
int comp(p a,p b){
return a.first<b.first;
}
long long mod(long long sum,long long powe){
return (sum-(sum/powe)*powe);
}
int bins(vector<p> arr,long long start,long long end,long long search){
if(start>end)
return start;
int mid = (start+end)/2;
if(arr[mid].first==search)
return mid;
else if(arr[mid].first<search)
return bins(arr,mid+1,end,search);
else
return bins(arr,start,mid-1,search);
}
void reverse(string s){
int i=0;
int j=s.length()-1;
while(j>=0){
cout<<s[j];
j--;
}
}
void process(long long num)
{
string s="";
int i=0;
while(i<8){
s+=num%10+'0';
num/=10;
if(num==0){
while(i<7){
s+='0';
i++;
}
break;
}
i++;
}
reverse(s);
cout<<"\n";
}
long long func(vector<p> arr)
{
int n=arr.size();
ans[n-1]=1;
long long sum=ans[n-1];
cuml_sum[n-1]=ans[n-1];
for(int i=n-2;i>=0;i--){
int j=bins(arr,i+1,n-1,arr[i].second);
if(j>n-1)
{
ans[j]=0;
cuml_sum[j]=0;
}
ans[i]=1+cuml_sum[j];
cuml_sum[i]=ans[i]+cuml_sum[i+1];
sum+=ans[i];
}
return mod(sum,(long long)pow(10,8));
}
int main(void){
vector<p> arr;
int test,n;
for(int i=0;i<100000;i++){
ans.push_back(0);
cuml_sum.push_back(0);
}
long long a,b;
while(1){
cin>>n;
if(n==-1)
return 0;
for(int i=0;i<n;i++){
cin>>a>>b;
arr.push_back(p(a,b));
}
sort(arr.begin(),arr.end(),comp);
process(func(arr));
arr.clear();
}
return 0;
}