感觉已经快成御用验题小天使 = =。。
姜神出的题,然后cyx小朋友成功AK了
【T1】 排队 Waiting
这题和之前有一道NOIp题差不多。。做法也是一样的。。排个序就万事大吉了。
听说有人最后计算结果的时候少算了b,然后出了点儿事。。。
#include <cstdio>
#include <iostream>
#include <algorithm>
#define Mod 1000000009ll
using namespace std;
int N, a[10005], b[10005], w[10005];
bool cmp(const int &i, const int &j) { return a[i] * b[j] < a[j] * b[i]; };
int main()
{
freopen("waiting.in", "r", stdin);
freopen("waiting.out", "w", stdout);
ios :: sync_with_stdio(false);
cin >> N;
for (int i = 1; i <= N; ++ i) {
cin >> a[i] >> b[i]; w[i] = i;
}
sort(w + 1, w + N + 1, cmp);
long long ans = 0ll;
for (int i = 1; i <= N; ++ i) {
ans += ans * b[w[i]] + a[w[i]];
if (ans > Mod) ans %= Mod;
}
cout << ans << endl;
return 0;
}
【T2】树上未解之谜
毕竟这玩意儿是我意淫出来的。。。但是改成二叉树君就太水了……直接把N^2变成了loglog
于是乎暴力玩玩就出来了……姜神的做法好像很诡异啊而且效率还没暴力高…………
#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
const long long mod = 1000000009;
int N, M, w[20005], high;
int sum[20005], num[20005][20], add[20];
#define lc (u << 1)
#define rc (u << 1 | 1)
void dfs(int u, int dep)
{
if (u > N) return;
++ num[u][dep]; sum[u] = w[u];
dfs(lc, dep + 1); dfs(rc, dep + 1);
sum[u] += sum[lc] + sum[rc];
for (int i = dep + 1; i <= high; ++ i)
num[u][i] += num[lc][i] + num[rc][i];
}
int main()
{
freopen("treeplus.in", "r", stdin);
freopen("treeplus.out", "w", stdout);
ios :: sync_with_stdio(false);
cin >> N >> M;
high = (int) (log(N) / log(2)) + 1;
for (int i = 1; i <= N; ++ i) cin >> w[i];
dfs(1, 1);
int sign, a, b;
while (M --) {
cin >> sign;
if (sign == 1) {
cin >> a >> b; add[a] += b;
} else {
cin >> a; long long ans = sum[a];
for (int i = 1; i <= high; ++ i) {
ans += (long long)add[i] * num[a][i];
if (ans > mod) ans %= mod;
}
cout << ans << endl;
}
}
return 0;
}
【T3】线段覆盖
姜神最开始的数据出了点问题……于是就一直拍不上…………大早上起来改数据心塞……
两棵线段树就可以搞定了……不知道能不能合到一起去。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int N, M, l[1000005], r[1000005], bfr[2000005];
#define lowbit(i) (i & -i)
namespace BIT {
int d[2000005][2];
inline void Add(int pos, int c)
{
for (int i = pos; i <= 2000000; i += lowbit(i))
++ d[i][c];
}
inline int Query(int pos, int c)
{
int ans = 0;
for (int i = pos; i; i -= lowbit(i))
ans += d[i][c];
return ans;
}
}
int main()
{
freopen("segment.in", "r", stdin);
freopen("segment.out", "w", stdout);
ios :: sync_with_stdio(false);
cin >> N; int L, R;
for (int i = 1; i <= N; ++ i) {
cin >> L; R = L + i - 1;
cout << BIT :: Query(R, 1) - BIT :: Query(L - 1, 0) << endl;
BIT :: Add(L, 0); BIT :: Add(R, 1);
}
return 0;
}
【T4】魔法门
人生的第二道计算几何……调了好久居然是因为数组炸了。。
为什么溢出不会RE而会直接覆盖。。。
写了两个版本有一个会超时……另一个好像效率还蛮高的…………
还是觉得几何这种东西好烦TAT
然后最后这题被砍了……因为超纲了……不过练代码能力还是ok的……
#include <cstdio>
#include <iostream>
#include <cmath>
#include <queue>
#define eps 1e-15
using namespace std;
int N;
struct Point {
double x, y;
}P[5050];
struct Vector {
Point s, e;
}wall[1050], Line[505 * 5050];
int cntw, cntl, cntp;
struct LinePoint {
int sp, ep;
}lp[505 * 5050];
Vector SetLine(const double &sx, const double &sy, const double &ex, const double &ey)
{
Point ss = (Point) { sx, sy };
Point ee = (Point) { ex, ey };
return (Vector) { ss, ee };
}
inline double Cross(Point A, Point B, Point O)
{ // OA × OB
return (A.x - O.x) * (B.y - O.y) - (B.x - O.x) * (A.y - O.y);
}
bool intersect(Vector u, Vector v)
{ // 判断线段相交
return ( Cross(v.s, u.e, u.s) * Cross(u.e, v.e, u.s) > eps &&
Cross(u.s, v.e, v.s) * Cross(v.e, u.e, v.s) > eps );
}
inline double Distance(double x1, double y1, double x2, double y2)
{
return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
namespace spfa {
struct ed {
int v, next;
double w;
}e[505 * 505 * 20];
int head[5050], k = 1;
inline void adde(int u, int v, double w)
{
e[k] = (ed) {v, head[u], w};
head[u] = k ++;
}
queue <int> q;
double dis[5050];
bool vis[5050];
double SPFA(int S, int T)
{
for (int i = 1; i <= cntp; ++ i) dis[i] = 1e100;
dis[S] = 0. ; q.push(S);
while (q.size()) {
int u = q.front(); q.pop(); vis[u] = 0;
for (int i = head[u]; i; i = e[i].next) {
int v = e[i].v;
if (dis[v] - eps > dis[u] + e[i].w) {
dis[v] = dis[u] + e[i].w;
if (!vis[v]) { vis[v] = 1; q.push(v); }
}
}
}
return dis[T];
}
}
int main()
{
freopen("door.in", "r", stdin);
freopen("door.out", "w", stdout);
cin >> N; double x, a, b, c, d;
P[++ cntp] = (Point) { 0. , 5. }; int S = cntp;
for (int i = 1; i <= N; ++ i) {
cin >> x >> a >> b >> c >> d;
wall[++ cntw] = SetLine(x, 0, x, a);
wall[++ cntw] = SetLine(x, b, x, c);
wall[++ cntw] = SetLine(x, d, x, 10);
P[++ cntp] = (Point) { x, a };
P[++ cntp] = (Point) { x, b };
P[++ cntp] = (Point) { x, c };
P[++ cntp] = (Point) { x, d };
}
P[++ cntp] = (Point) { 10. , 5. }; int T = cntp;
for (int i = 1; i <= cntp; ++ i) {
for (int j = 1; j <= cntp; ++ j) {
Line[++ cntl] = SetLine(P[i].x, P[i].y, P[j].x, P[j].y);
lp[cntl] = (LinePoint) { i, j };
}
}
for (int i = 1; i <= cntl; ++ i) {
bool flag = 1;
if (lp[i].sp == 2) {
int a = 1;
}
for (int j = 1; j <= cntw; ++ j) if (intersect(Line[i], wall[j])) {
flag = 0; break;
}
if (! flag) continue;
int u = lp[i].sp, v = lp[i].ep;
double w = Distance(Line[i].s.x, Line[i].s.y, Line[i].e.x, Line[i].e.y);
spfa :: adde(u, v, w);
}
printf("%.2f\n", spfa :: SPFA(S, T));
return 0;
}