1、一个机器人有$m$个部分。有$n$台机器,第$i$个机器可以生产编号为$[a_{i},b_{i}]$区间的部分,最多可以生产$k_{i}$个部分。最多可以组装成多少个机器?
思路:二分答案。然后判断。将所有的机器按照$a_{i}$排序,$a_{i}$相同的按照$b_{i}$排序。用一个优先队列维护这些机器。这样对于第$i$个部分,拿出队列开始的机器来生产该部分;如果队列开头的机器生产的部分没用完,则将其左区间$a_{t}$设置为$a_{t}+1$然后重新塞到队列里。
#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <stack>
#include <assert.h>
using namespace std;
const int N=10000000;
int n,m;
int c[N],a[N],b[N];
struct node
{
int L,R,cnt;
node(){}
node(int _L,int _R,int _cnt):L(_L),R(_R),cnt(_cnt) {}
int operator<(const node& A) const
{
if(L!=A.L) return L>A.L;
return R>A.R;
}
};
priority_queue<node> Q;
int check(const int M)
{
if(!M) return 1;
while(!Q.empty()) Q.pop();
for(int i=1;i<=n;++i) Q.push(node(a[i],b[i],c[i]));
for(int i=1;i<=m;++i)
{
if(Q.empty()) return 0;
int sum=0;
while(sum<M)
{
if(Q.empty()) return 0;
if(Q.top().L!=i) return 0;
if(sum+Q.top().cnt<=M)
{
sum+=Q.top().cnt;
Q.pop();
}
else
{
node p=Q.top(); Q.pop();
p.cnt-=M-sum;
++p.L;
if(p.L<=p.R) Q.push(p);
break;
}
}
while(!Q.empty()&&Q.top().L==i)
{
node p=Q.top(); Q.pop();
++p.L;
if(p.L<=p.R) Q.push(p);
}
}
return 1;
}
class FleetFunding
{
public:
int maxShips(int mm,vector<int> kk,vector<int> aa,vector<int> bb)
{
n=(int)kk.size();
m=mm;
int sum=0;
for(int i=1;i<=n;++i)
{
c[i]=kk[i-1];
a[i]=aa[i-1];
b[i]=bb[i-1];
sum+=c[i];
}
int low=0,high=sum/m;
int ans=0;
while(low<=high)
{
int M=(low+high)>>1;
if(check(M)) ans=max(ans,M),low=M+1;
else high=M-1;
}
return ans;
}
};
2、一个长度为$n$的数组$A$,$B_{i}=max(k|A_{i-k}<A_{i}$且$A_{i+k}<A_{i})$。返回$\sum_{i=0}^{n-1}B_{i}$。给定$0\leq x_{0},a,b < 2^{50}$。数组$A$的产生方式如下。这个题目要求内存大小是$O(1)$,即不能开数组存储$A$。
A[0] = x0
for i = 1 to n-1:
A[i] = ((A[i-1] XOR a) + b) AND ((2^50) - 1)
思路:首先由$A_{i}$得到$A_{i-1}$的方式为$A_{i-1}=((A_{i}+2^{50}-b)$^$a)$&$(2^{50}-1)$。然后就是一个数字一个数字暴力计算$B$值。总的累积复杂度是$O(n)$的。
#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <stack>
#include <assert.h>
using namespace std;
const int mod=1000000007;
const long long M=(1ll<<50)-1;
long long a,b;
long long NextX(long long x)
{
return ((x^a)+b)&M;
}
long long PreX(long long x)
{
return ((x+M+1-b)^a)&M;
}
int cal(int id,long long x,int n)
{
int ll=id,rr=id;
int ans=0;
long long lx=x,rx=x;
while(ll-1>=0&&rr+1<n)
{
lx=PreX(lx);
rx=NextX(rx);
if(lx<x&&x>rx) ++ans,--ll,++rr;
else break;
}
return ans;
}
class LimitedMemorySeries2
{
public:
int getSum(int n,long long x0,long long aa,long long bb)
{
a=aa;
b=bb;
int ans=0;
long long t=x0;
for(int i=0;i<n;++i)
{
ans+=cal(i,t,n);
if(ans>=mod) ans-=mod;
t=NextX(t);
}
return ans;
}
};
原文:http://www.cnblogs.com/jianglangcaijin/p/7003187.html