A 傻缺题,直接先把素数搞出来然后枚举一下就好了。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 1e4 + 10;
bool vis[maxn];
vector<int> pnum;
void init() {
vis[1] = true;
int maxv = 10000;
for(int i = 2; i <= maxv; i++) if(!vis[i]) {
pnum.push_back(i);
for(int j = i + i; j <= maxv; j += i) vis[j] = true;
}
}
void gao(int num) {
int ans = 0;
int msize = pnum.size();
for(int i = 0; i < msize; i++) {
for(int j = i; j < msize && pnum[i] + pnum[j] < num; j++) {
int tt = num - pnum[i] - pnum[j];
if(!vis[tt] && tt >= pnum[j]) ans++;
if(tt < pnum[j]) break;
}
}
printf("%d\n", ans);
}
int main() {
init();
int n;
while(scanf("%d", &n) != EOF) {
gao(n);
}
return 0;
}
B 直接求导之后找极值点就好了,注意特判a,b等于0的情况。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const double eps = 1e-9;
int getx2p(double a, double b, double c, double &x1, double &x2) {
double delta = b * b - 4 * a * c;
if(delta < 0) return 0;
x1 = -b + sqrt(delta); x2 = -b - sqrt(delta);
x1 /= 2 * a; x2 /= 2 * a;
if(delta < eps) return 1;
else return 2;
}
bool inrange(double n, double L, double R) {
L -= eps; R += eps;
return (n >= L && n <= R);
}
double f(double x, double a, double b, double c, double d) {
return a * x * x * x + b * x * x + c * x + d;
}
int main() {
double a, b, c, d, L, R;
while(scanf("%lf%lf%lf%lf%lf%lf", &a, &b, &c, &d, &L, &R) != EOF) {
double p0, p1;
int ret = getx2p(3 * a, 2 * b, c, p0, p1);
double ans = -1e30;
if(a == 0 && b == 0) {
ans = max(abs(f(L, a, b, c, d)), abs(f(R, a, b, c, d)));
}
else if(a == 0) {
ans = max(abs(f(L, a, b, c, d)), abs(f(R, a, b, c, d)));
double mid = -c / (2 * b);
if(inrange(mid, L, R)) {
ans = max(ans, f(mid, a, b, c, d));
}
}
else if(ret == 0 || (!inrange(p0, L, R) && !inrange(p1, L, R))) {
ans = max(abs(f(L, a, b, c, d)), abs(f(R, a, b, c, d)));
}
else {
ans = max(abs(f(L, a, b, c, d)), abs(f(R, a, b, c, d)));
if(inrange(p0, L , R)) ans = max(ans, abs(f(p0, a, b, c, d)));
if(inrange(p1, L , R)) ans = max(ans, abs(f(p1, a, b, c, d)));
}
printf("%.2f\n", ans);
}
return 0;
}
C 数位DP,思路和HDU 4507很像,也可以用排列组合直接搞。。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long LL;
const int maxn = 1e3 + 100;
const LL mod = 1e9 + 7;
char buf[maxn];
int lim[maxn], n, len;
LL p2[maxn];
bool vis[maxn][maxn];
struct EE {
LL cnt, sum;
EE(LL cnt = 0, LL sum = 0): cnt(cnt), sum(sum) {}
};
EE f[maxn][maxn];
EE dfs(int now, int bitcnt, bool bound) {
if(now == 0) return EE(bitcnt == 0, 0);
if(vis[now][bitcnt] && !bound) return f[now][bitcnt];
int m = bound ? lim[now - 1] : 1;
EE ret(0, 0);
for(int i = 0; i <= m; i++) {
EE nret = dfs(now - 1, bitcnt - i, bound && i == m);
LL ff = p2[now - 1] * i % mod;
ret.cnt = (ret.cnt + nret.cnt) % mod;
ret.sum = ((nret.cnt * ff % mod + nret.sum) % mod + ret.sum) % mod;
}
if(!bound) {
vis[now][bitcnt] = true;
f[now][bitcnt] = ret;
}
return ret;
}
void gao() {
len = strlen(buf);
bool flag = false;
for(int i = 0, j = len - 1; i < len; i++, j--) {
lim[j] = buf[i] - '0';
}
int pos;
for(pos = 0; lim[pos] == 0; pos++) lim[pos] = 1;
lim[pos] = 0;
if(pos == len - 1) len--;
EE ret = dfs(len, n, true);
cout << ret.sum << endl;
}
void init() {
p2[0] = 1;
for(int i = 1; i <= 1000; i++) {
p2[i] = (p2[i - 1] * 2) % mod;
}
}
int main() {
init();
while(scanf("%d%s", &n, buf) != EOF) {
gao();
}
return 0;
}
D 线段树
先把所有的点按照y排序,然后在x轴上一个一个插入然后统计即可。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
const int maxn = 3e4 + 100;
const int inf = 1e9 + 100;
struct Node {
int val[12];
Node() {
for(int i = 1; i <= 11; i++) val[i] = inf;
}
void Megre(int val1[12]) {
int tar[22];
for(int i = 1; i <= 10; i++) {
tar[i] = val[i]; tar[i + 10] = val1[i];
}
sort(tar + 1, tar + 21);
for(int i = 1; i <= 10; i++) val[i] = tar[i];
val[11] = inf;
}
void Megre(int k) {
val[11] = k;
sort(val + 1, val + 12);
val[11] = inf;
}
void print() {
for(int i = 1; i <= 10; i++) {
printf("%d ", val[i]);
}
puts("");
}
};
Node minv[maxn << 4];
void pushup(int rt) {
minv[rt] = minv[rt << 1];
minv[rt].Megre(minv[rt << 1 | 1].val);
}
void build(int rt, int l, int r) {
if(l == r) minv[rt] = Node();
else {
int mid = (l + r) >> 1;
build(lson); build(rson);
pushup(rt);
}
}
void update(int rt, int l, int r, int pos, int x) {
if(l == r) minv[rt].Megre(x);
else {
int mid = (l + r) >> 1;
if(pos <= mid) update(lson, pos, x);
else update(rson, pos, x);
pushup(rt);
}
}
Node query(int rt, int l, int r, int ql, int qr) {
if(ql <= l && qr >= r) return minv[rt];
else {
int mid = (l + r) >> 1;
Node ret = Node();
if(ql <= mid) ret.Megre(query(lson, ql, qr).val);
if(qr > mid) ret.Megre(query(rson, ql, qr).val);
return ret;
}
}
struct Point {
int x, y, h, k;
int id;
bool isq;
Point(int x, int y, int h, bool isq, int k = 0, int id = 0):
x(x), y(y), h(h), isq(isq), k(k), id(id) {}
bool operator < (const Point &p) const {
if(y == p.y) return x < p.x;
return y < p.y;
}
};
int n, m, ans[maxn];
vector<int> vnum;
vector<Point> pp;
int getid(int val) {
int ret = lower_bound(vnum.begin(), vnum.end(), val) - vnum.begin() + 1;
return ret;
}
int main() {
while(scanf("%d%d", &n, &m) != EOF) {
vnum.clear(); pp.clear();
for(int i = 1; i <= n; i++) {
int x, y, h; scanf("%d%d%d",&x, &y, &h);
pp.push_back(Point(x, y, h, false));
vnum.push_back(x);
}
for(int i = 1; i <= m; i++) {
int x, y, k;
scanf("%d%d%d", &x, &y, &k);
pp.push_back(Point(x, y, 0, true, k, i));
vnum.push_back(x);
}
sort(vnum.begin(), vnum.end());
sort(pp.begin(), pp.end());
vnum.erase(unique(vnum.begin(), vnum.end()), vnum.end());
int mm = pp.size(), nn = vnum.size();
build(1, 1, nn);
for(int i = 0; i < mm; i++) {
if(pp[i].isq == false) {
update(1, 1, nn, getid(pp[i].x), pp[i].h);
}
else {
Node ret = query(1, 1, nn, 1, getid(pp[i].x));
ans[pp[i].id] = ret.val[pp[i].k];
}
}
for(int i = 1; i <= m; i++) {
if(ans[i] == inf) ans[i] = -1;
printf("%d\n", ans[i]);
}
}
return 0;
}