NOIP2016

一͛世͛珍͛藏͛發表於2019-05-12
/*
    http://gk.qhyedu.com/qhy/20161121/94268.html
    http://gk.qhyedu.com/qhy/20161121/94269.html
*/

running.cpp

#include <cstdio>

class UnionFindSets {
    int *father, *rank;
public:
    UnionFindSets(int N) {
        father = new int[N], rank = new int[N];
        for(int x=0; x<N; x++) father[x] = x, rank[x] = 1;
    }
    int FindSets(int x) {
        if(x != father[x]) father[x] = FindSets(father[x]);
        return father[x];
    }
    bool SameSets(int x, int y) {
        return FindSets(x) == FindSets(y);
    }
    void UnionSets(int x, int y) {
        if((x = FindSets(x)) == (y = FindSets(y))) return;
        if(rank[x] <= rank[y]) father[x] = y, rank[y] += rank[x];
        else                   father[y] = x, rank[x] += rank[y];
    }
    ~UnionFindSets() {
        delete[] father, delete[] rank;
    }
};

struct Edge { int v; Edge *next; };
struct Path { int v; Path *next; bool arrow; };
struct Node { int v, depth; };
struct Pair { int a, b, lca; };

class Tarjan : public UnionFindSets {
    bool *visited;
    int *ancestor;
    Edge **edge;
    Path **path;
    void lca(int x, int top, Node g[], Pair *&q) {
        for(Edge *e=edge[x]; e; e=e->next) {
            if(e->v==top) continue;
            g[e->v] = (Node){x, g[x].depth+1};
            lca(e->v, x, g, q);
            UnionSets(x, e->v);
            ancestor[FindSets(e->v)] = x;
        }
        visited[x] = true;

        for(Path *p=path[x]; p; p=p->next) {
            if(!visited[p->v]) continue;
            *q++ = p->arrow
                 ? (Pair){x, p->v, ancestor[FindSets(p->v)]}
                 : (Pair){p->v, x, ancestor[FindSets(p->v)]};
        }
    }
public:
    Tarjan(int N, Edge *e[], Path *p[]) : UnionFindSets(N) {
        visited = new bool[N], ancestor = new int[N];
        for(int x=0; x<N; x++)
            visited[x] = false, ancestor[x] = x, e[x] = NULL, p[x] = NULL;
        edge = e, path = p;
    }
    void LCA(Node g[], Pair q[]) {
        g[0] = (Node){0, 0};
        lca(0, -1, g, q);
    }
    ~Tarjan() {
        delete[] visited, delete[] ancestor;
    }
};

void read_data(int n, Node g[], int w[], int m, Pair q[]) {
    Edge *edge[n], _edge[2][n-1];
    Path *path[n], _path[2][m];
    Tarjan tarjan(n, edge, path);

    for(int i=0; i<n-1; i++) {
        int u, v;
        scanf("%d%d", &u, &v); u--, v--;
        _edge[0][i] = (Edge){v, edge[u]}, edge[u] = _edge[0]+i;
        if(u==v) continue;
        _edge[1][i] = (Edge){u, edge[v]}, edge[v] = _edge[1]+i;
    }
    for(int i=0; i<n; i++) scanf("%d", w+i);
    for(int i=0; i<m; i++) {
        int s, t;
        scanf("%d%d", &s, &t); s--, t--;
        _path[0][i] = (Path){t, path[s], true }, path[s] = _path[0]+i;
        if(s==t) continue;
        _path[1][i] = (Path){s, path[t], false}, path[t] = _path[1]+i;
    }

    tarjan.LCA(g, q);
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);

    Node g[n];
    int  w[n];
    Pair q[m];
    read_data(n, g, w, m, q);

    int  c[n];
    for(int i=0; i<n; i++) c[i] = 0;
    for(int i=0; i<m; i++) {
        int s = 0;
        int t = g[q[i].a].depth - g[q[i].lca].depth
              + g[q[i].b].depth - g[q[i].lca].depth;
        for(int v=q[i].a; v!=q[i].lca; v=g[v].v)
            if(s++==w[v]) c[v]++;
        for(int v=q[i].b; v!=q[i].lca; v=g[v].v)
            if(t--==w[v]) c[v]++;
        if(t==w[q[i].lca]) c[q[i].lca]++;
    }
    for(int i=0; i<n; i++) printf("%d ", c[i]);
    printf("
");
    return 0;
}

classroom.cpp

#include <iostream>
using namespace std;

struct phase {
    int c,d;
    float k;
};
const int INF = ((unsigned)-1)>>2;

float f(int *g[], int cd, phase *p, int n, int m) {
    if(n<=0) return 0;
    float f0 = (g[cd][p->c]+f(g,p->c,p+1,n-1,m));
    if(!m--) return f0;
    float f1 = (g[cd][p->d]+f(g,p->d,p+1,n-1,m))*p->k
             + (g[cd][p->c]+f(g,p->c,p+1,n-1,m))*(1-p->k);
    return min(f0, f1);
}

float F(int *g[], phase *p, int n, int m) {
    float f0 = f(g,p->c,p+1,n-1,m);
    if(!m--) return f0;
    float f1 = f(g,p->d,p+1,n-1,m)*p->k
             + f(g,p->c,p+1,n-1,m)*(1-p->k);
    return min(f0, f1);
}

int main() {
    int n, m, v, e;
    scanf("%d%d%d%d
", &n, &m, &v, &e);

    phase p[n];
    for(int i=0; i<n; i++) scanf("%d", &p[i].c), p[i].c--;
    for(int i=0; i<n; i++) scanf("%d", &p[i].d), p[i].d--;
    for(int i=0; i<n; i++) scanf("%f", &p[i].k);

    int _g[v][v], *g[v];
    for(int i=0; i<v; i++) g[i] = _g[i];
    for(int i=0; i<v; i++) {
        g[i][i] = 0;
        for(int j=i+1; j<v; j++) g[j][i] = g[i][j] = INF;
    }
    for(int i=0; i<e; i++) {
        int a, b, w;
        scanf("%d%d%d", &a, &b, &w), a--, b--;
        g[b][a] = g[a][b] = min(g[a][b], w);
    }
    for(int k=0; k<v; k++)
        for(int i=0; i<v; i++)
            for(int j=i+1; j<v; j++)
                g[j][i] = g[i][j] = min(g[i][j], g[i][k]+g[k][j]);

    printf("%.2f
", F(g,p,n,m)+0.005);
    return 0;
}

problem.cpp

#include <iostream>
using namespace std;

int C[2001][2001];

int L(int i, int k) {
    int count = 0;
    while(i%k == 0) i/=k, count++;
    return count;
}

void init(int k) {
    C[0][0] = 0;
    for(int i=1; i<=2000; i++)
        for(int j=0; j<=i; j++)
            C[i][j] = (2*j>i) ? C[i][i-j] : C[i-1][j]+L(i,k)-L(i-j,k);
}

int main() {
    int t, k;
    scanf("%d %d
", &t, &k);

    init(k);
    while(t-->0) {
        int n, m;
        scanf("%d %d
", &n, &m);

        int count = 0;
        for(int i=0; i<=n; i++)
            for(int j=0; j<=min(i,m); j++)
                if(C[i][j]) count++;
        printf("%d
", count);
    }
    return 0;
}

earthworm.cpp

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

struct worm {
    static int q;
    int len, sec;
    bool operator() (const worm& l, const worm& r) {
        return l.len-l.sec*l.q <= r.len-r.sec*r.q;
    }
};
int worm::q = 0;

int main() {
    int n, m, u, v, t;
    scanf("%d %d %d %d %d %d
", &n, &m, &worm::q, &u, &v, &t);

    priority_queue<worm, vector<worm>, worm> heap;
    for(int i=1; i<=n; i++) {
        worm a;
        scanf("%d ", &a.len), a.sec = 0;
        heap.push(a);
    }
    scanf("
");

    for(int i=1; i<=m; i++) {
        worm a = heap.top(); heap.pop();
        int len = a.len+(i-1-a.sec)*a.q;
        if(i%t==0) printf("%d ", len);
        a.sec = i;
        a.len = len * u/v, heap.push(a);
        a.len = len-a.len, heap.push(a);
    }
    printf("
");

    for(int i=1; /*i<=n+m*/heap.size(); i++) {
        worm a = heap.top(); heap.pop();
        if(i%t==0) printf("%d ", a.len+(m-a.sec)*a.q);
    }
    printf("
");
    return 0;
}

angrybirds.cpp

#include <iostream>
using namespace std;

struct pig {
    static float x0, y0;
    float x, y;
    float a() const {
        return (x==x0) ? 1e10 : (y-y0)/(x-x0);
    }
    bool operator() (const pig& l, const pig& r) const {
        return l.a() > r.a();
    }
};
float pig::x0 = 0;
float pig::y0 = 0;

int birds(pig *p, int n) {
    if(!n) return 0;
    pig::x0 = p->x;
    pig::y0 = p->y;
    sort(p+1, p+n, *p);

    float ca = 0;
    int   cs = 0, ps = 0;
    int   cc = 0, pc = 0;
    for(int i=1; i<n; i++) {
        float a = p[i].a();
        if(a>=0) continue;
        if(ca-a<0.001) cc++;
        else if(cc>=pc) ps=cs, pc=cc, ca=a, cs=i, cc=1;
    }
    if(cc>=pc) ps=cs, pc=cc;
    if(ps!=1)
        for(int i=0; i<pc; i++) swap(p[1+i], p[ps+i]);
    return 1+birds(p+1+pc, n-1-pc);
}

int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        int n, m;
        scanf("%d%d", &n, &m);

        pig p[n];
        for(int i=0; i<n; i++) {
            scanf("%f%f", &p[i].x, &p[i].y);
            p[i].y /= p[i].x;
        }

        printf("%d
", birds(p, n));
    }
    return 0;
}