码迷,mamicode.com
首页 > 其他好文 > 详细

省选测试4

时间:2021-02-04 12:07:29      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:wap   主席树   operator   char   his   强制   dfs   struct   end   

技术图片
这可怜的分数

A 点点的圈圈

  • 考场上强转的时候1ll写成了1l,60变28??

  • 将最小包含自己的圆当作父亲,跑一个简单的树形DP就可以求出答案,考虑如何找父亲

  • 扫描线,将扫到的圆的上下面分别加到set里,新加一个点的时候找y坐标第一个比它大的半圆,如果这个半圆是上半圆,那一定是它父亲,否则就是兄弟

  • 我写这篇其实主要不是为了题解,而是关于using namespace std;

  • 在郭神加强数据之后,一直TLE,看着比我写的还丑的HISKrrr都过了,调了一晚上,最后去掉std::,换上using namspace std;然后就过了

  • 从今往后,如果再有人敢在我面前说写std::这样好那样好,我就当场把那个人的头咬下来!!!

Show Code
#include <set>
#include <cmath>
#include <cstdio>
#include <algorithm>

using namespace std;
const int N = 1e5 + 5;

int read(int x = 0, int f = 1, char c = getchar()) {
    for (; c < ‘0‘ || c > ‘9‘; c = getchar())
        if (c == ‘-‘) f = -1;
    for (; c >=‘0‘ && c <=‘9‘; c = getchar())
        x = x * 10 + c - ‘0‘;
    return x * f;
}

struct Edge {
    int n, t;
}e[N];
int h[N], edc;

void Add(int x, int y) {
    e[++edc] = (Edge) {h[x], y}; h[x] = edc;
}

int n, x[N], y[N], r[N], w[N], fa[N], X, m;

struct Node {
    int i, k;
    double Cal() const {
        return y[i] + k * sqrt(1ll * r[i] * r[i] - 1ll * (x[i] - X) * (x[i] - X));
    }
};
set<Node> s;
set<Node>::iterator it;

bool operator < (const Node &a, const Node &b) {
    double ya = a.Cal(), yb = b.Cal();
    return ya != yb ? ya < yb : a.k < b.k;
}

struct Node2 {
    int x, i, k;
}a[N*2];

bool operator < (const Node2 &a, const Node2 &b) {
    return a.x < b.x;
}

int Dfs(int x) {
    int s = 0;
    for (int i = h[x]; i; i = e[i].n)
        s += Dfs(e[i].t);
    return s > w[x] ? s : w[x];
}

int main() {
    n = read();
    for (int i = 1; i <= n; ++i) {
        x[i] = read(), y[i] = read(), r[i] = read(), w[i] = read();
        a[++m] = (Node2) {x[i] - r[i], i, 1};
        a[++m] = (Node2) {x[i] + r[i], i, 0};
    }
    sort(a + 1, a + m + 1);
    for (int j = 1; X = a[j].x, j <= m; ++j) {
        if (!a[j].k) s.erase((Node) {a[j].i, 1}), s.erase((Node) {a[j].i, -1});
        else {
            int z = a[j].i; it = s.lower_bound((Node) {z, 1});
            if (it != s.end()) fa[z] = it->k == 1 ? it->i : fa[it->i];
            s.insert((Node) {z, 1}), s.insert((Node) {z, -1});
        }
    }
    for (int i = 1; i <= n; ++i) Add(fa[i], i);
    printf("%d\n", Dfs(0));
    return 0;
}

B 点点的计算

  • 经过一系列推导,可得出ans(n,k)=lcm(n-k+1,n-k+2,…,n)

  • 然后就是维护一个长为r的数组a,令

\[\prod_{i=l}^{r}a_i=lcm(l,l+1,...,r) \]

  • 考虑已经求出长为r-1的数组,怎么维护长为r的数

  • 其实就是把r质因数分解,然后在前面找到这个质因数在哪出现的,删去就好了

  • 多组询问且强制在线的话写个主席树就好了

Show Code
#include <cstdio>
#include <algorithm>
#define ls t[rt].l
#define rs t[rt].r

using namespace std;
const int N = 1e5 + 5, M = 1e9 + 7;

int read(int x = 0, int f = 1, char c = getchar()) {
    for (; c < ‘0‘ || c > ‘9‘; c = getchar())
        if (c == ‘-‘) f = -1;
    for (; c >=‘0‘ && c <=‘9‘; c = getchar())
        x = x * 10 + c - ‘0‘;
    return x * f;
}

int q, n, k, a, b, m, c[N*2], d[N*2], ans;
int pri[N], tot, v[N], inv[N], s[N], rt[N], trc;

struct Tree {
    int s, l, r;
    Tree() { s = 1; }
}t[N*80];

void Add(int &rt, int l, int r, int x, int w) {
    t[++trc] = t[rt]; rt = trc;
    t[rt].s = 1ll * t[rt].s * w % M;
    if (l == r) return;
    int mid = l + r >> 1;
    if (x <= mid) Add(ls, l, mid, x, w);
    else Add(rs, mid + 1, r, x, w);
}

int Ask(int rt, int l, int r, int x, int y) {
    if (x <= l && r <= y) return t[rt].s;
    int mid = l + r >> 1, ans = 1;
    if (x <= mid) ans = Ask(ls, l, mid, x, y);
    if (y > mid) ans = 1ll * ans * Ask(rs, mid+1, r, x, y) % M;
    return ans;
}

int main() {
    q = read(); n = read(); k = read();
    a = read(); b = read(); m = read();
    for (int i = 1; i < q; ++i) c[i] = read();
    for (int i = 1; i < q; ++i) d[i] = read();
    inv[1] = 1; 
    for (int i = 2; i <= m; ++i) {
        inv[i] = 1ll * (M - M / i) * inv[M%i] % M;
        if (!v[i]) pri[++tot] = i, v[i] = i;
        for (int j = 1; j <= tot && i * pri[j] <= m; ++j) {
            v[i*pri[j]] = pri[j];
            if (i % pri[j] == 0) break;
        }
    }
    for (int i = 2; i <= m; ++i) {
        int x = i, p; Add(rt[i] = rt[i-1], 1, m, i, i);
        while (p = v[x]) {
            int cnt = 0, mul = p;
            while (x % p == 0) x /= p, cnt++;
            if (cnt > s[p]) swap(cnt, s[p]);
            while (cnt--) Add(rt[i], 1, m, i - mul, inv[p]), mul *= p;
        }
    }
    for (int i = 1; i <= q; ++i) {
        printf("%d\n", ans = Ask(rt[n], 1, m, n - k + 1, n));
        n = (1ll * a * ans + c[i]) % m + 1;
        k = (1ll * b * ans + d[i]) % n + 1;
    }
    return 0;
}

C 点点的最大流 (Unaccepted)

  • 反向边边权设为了0,于是33分没了
Show Code

省选测试4

标签:wap   主席树   operator   char   his   强制   dfs   struct   end   

原文地址:https://www.cnblogs.com/shawk/p/14290185.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!