【A. Divisibility】
【题目大意】输出[a,b]中能被k整除的数。
【分析】……我没看到负数……
代码:
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
long long a,b,k;
scanf("%I64d%I64d%I64d",&k,&a,&b);
if (a>0 && b>0) printf("%I64d",b/k-(a-1)/k);
if (a<=0 && b>=0) printf("%I64d",b/k-a/k+1);
if (a<0 && b<0) printf("%I64d",(b+1)/k-a/k);
}
【B. Restaurant】
【题目大意】有n个区间,第i 个区间的范围为[Li,Ri]问最多能选择几个不重叠的区间。
【分析】贪心,以R值从小到大排序,如果L比上一个R大,那么该区间就可以选择。一时脑残用了优先队列。
代码:
#include <cstdio>
#include <queue>
#include <vector>
#include <functional>
using namespace std;
typedef pair<int, int> pii;
priority_queue < pii, vector <pii>, greater<pii> > q;
pii a[500010];
using namespace std;
int main()
{
int n;
scanf("%d",&n);
for (int i=1; i<=n; i++) scanf("%d%d",&a[i].second,&a[i].first),q.push(a[i]);
int nowr=q.top().second-1,ans=0;
while (!q.empty())
{
int l=q.top().second,r=q.top().first; q.pop();
if (l<=nowr) continue;
ans++;
nowr=r;
}
printf("%d\n",ans);
}
【C. Subsequences】
【题目大意】给出1-n的一个排列,问长度为k+1的上升子序列的数量。
【分析】树状数组区间查询点修改。
代码:
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
inline int lowbit(int x) { return x&(-x); }
LL t[200020][12];
int n,m,k,a;
inline LL Sum(int x, int y) { LL res=0; for (x; x>0; x-=lowbit(x)) res+=t[x][y]; return res; }
void Change(int x, int y, LL d) { for (x; x<=100010; x+=lowbit(x)) t[x][y]+=d; }
int main()
{
scanf("%d%d",&n,&k);
for (int i=1; i<=n; i++)
{
scanf("%d",&a); m=max(m,a);
Change(a,1,1);
if (a==1) continue;
for (int j=2; j<=k+1; j++)
{
LL tt=Sum(a-1,j-1);
Change(a,j,tt);
}
}
printf("%I64d\n",Sum(100010,k+1));
}