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

8.15模拟赛

时间:2018-08-15 22:51:11      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:ring   ret   sig   font   ide   线段树   ble   一个   inline   

wzj大佬的模拟赛,蒟蒻又无情爆炸了,我只想弱弱的吐槽一句:这难度为什么是倒着来的啊qwq。。

T1题面

大意:给出一个n个浮点数(n<=50000)的序列和一个整数k(k<=20),每个点爆炸的概率为a[i](1<=i<=n),每段爆炸的贡献为连续爆炸的长度的k次方,求期望贡献

此题最高分50,写的全是n^2做法,我也不例外,因为正解实在没听懂,暂时留个坑吧,这种题放T1真是满满的槽点,贴个50的

技术分享图片
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
#define int long long
int n, k;
double g[50005], gg[1005][1005];
const int mod=1e6;
void reduce(double &x)
{
    int t = (int)(x);
    x = x - t / mod * mod;
}
signed main()
{
    scanf("%lld%lld", &n, &k);
    for(int i = 1; i <= n; i++)
    scanf("%lf", &g[i]);
    double ans = 0;
    for(int i = 1; i <= n; i++)
    {
        double now = g[i];
        gg[i][i] = g[i];
        for(int j = i + 1; j <= n; j++)
        now = now * g[j],
        gg[i][j] = now;
    }
    for(int i = 1; i <= n; i++)
    for(int j = 1; j + i - 1 <= n; j++)
    {
        double pp = gg[j][j + i - 1];
        int l = j, r = j + i - 1;
        if (l > 1) pp = pp * ((double)(1 - g[l - 1]));
        if (r < n) pp = pp * ((double)(1 - g[r + 1]));
        ans = ans + (double)(pp * pow(i, k));
    }
    reduce(ans);
    printf("%.4lf\n", ans);
}
View Code

T2题面

题不难啊,本场比赛码量担当,dfs序+线段树,pushup十分繁琐,以后有机会一定多练(可是时间已经不多了啊)

这是AC人数最多的一题 难度居中

技术分享图片
#include <cstdio>
#include <algorithm>
using namespace std;
#define inf 0x3f3f3f3f
int n, Q, B[200005], L[200005], ti = 0, pos[200005], id[200005], size[200005];
int tot = 0, Next[200005 << 1], to[200005 << 1], head[200005 << 1];
inline void add(int x, int y)
{
    Next[++tot] = head[x];
    to[tot] = y;
    head[x] = tot;
}
inline void dfs(int x)
{
    pos[x] = ++ti;
    id[ti] = x;
    size[x] = 1;
    for(int i = head[x]; i; i = Next[i])
    {
        int V = to[i];
        dfs(V);
        size[x] += size[V];
    }
}
struct SegmentTree
{
    int l, r, s, bmx, bcx, bcc, lmx, lcx;
}Tree[200005 << 2];
SegmentTree operator +(const SegmentTree &a,const SegmentTree &b)
{
    SegmentTree c;
    c.l = a.l;
    c.r = b.r;
    c.bcx = c.bcc = c.lcx = -inf;
    c.bmx = max(a.bmx, b.bmx);
    if (a.bmx > b.bmx) c.s = a.s;
    else if (a.bmx < b.bmx) c.s = b.s;
    else if (a.bmx == b.bmx) c.s = a.s + b.s;
    c.lmx = max(a.lmx, b.lmx);
    if (a.lmx != c.lmx && a.lmx > c.lcx) c.lcx = a.lmx;
    if (b.lmx != c.lmx && b.lmx > c.lcx) c.lcx = b.lmx;
    if (a.lcx != c.lmx && a.lcx > c.lcx) c.lcx = a.lcx;
    if (b.lcx != c.lmx && b.lcx > c.lcx) c.lcx = b.lcx;
    if (a.bmx != c.bmx && a.bmx > c.bcx) c.bcx = a.bmx;
    if (b.bmx != c.bmx && b.bmx > c.bcx) c.bcx = b.bmx;
    if (a.bcx != c.bmx && a.bcx > c.bcx) c.bcx = a.bcx;
    if (b.bcx != c.bmx && b.bcx > c.bcx) c.bcx = b.bcx;
    if (a.bmx != c.bmx && a.bmx != c.bcx && a.bmx > c.bcc) c.bcc = a.bmx;
    if (a.bcx != c.bmx && a.bcx != c.bcx && a.bcx > c.bcc) c.bcc = a.bcx;
    if (a.bcc != c.bmx && a.bcc != c.bcc && a.bcc > c.bcc) c.bcc = a.bcc;
    if (b.bmx != c.bmx && b.bmx != c.bcx && b.bmx > c.bcc) c.bcc = b.bmx;
    if (b.bcx != c.bmx && b.bcx != c.bcx && b.bcx > c.bcc) c.bcc = b.bcx;
    if (b.bcc != c.bmx && b.bcc != c.bcc && b.bcc > c.bcc) c.bcc = b.bcc;
    return c;
}
inline void build(int l, int r, int x)
{
    Tree[x].l = l;
    Tree[x].r = r;
    if (l == r)
    {
        Tree[x].s = 1;
        Tree[x].bmx = B[id[l]];
        Tree[x].lmx = L[id[l]];
        Tree[x].bcx = -inf;
        Tree[x].bcc = -inf;
        Tree[x].lcx = -inf;
        return;
    }
    int mid = (l + r)  >>  1;
    build(l, mid, x << 1);
    build(mid + 1, r, x << 1 | 1);
    Tree[x] = Tree[x << 1] + Tree[x << 1 | 1];
    return;
}
inline SegmentTree query(int l, int r, int x)
{
    if (l > r) return (SegmentTree){l, r, -inf, -inf, -inf, -inf, -inf, -inf};
    if (l <= Tree[x].l && Tree[x].r <= r) return Tree[x];
    int mid = (Tree[x].l + Tree[x].r) >> 1;
    if (r <= mid) return query(l, r, x << 1);
    else if (l > mid) return query(l, r, x << 1 | 1);
    else return query(l, mid, x << 1) + query(mid + 1, r, x << 1 | 1);
}
int main()
{
    scanf("%d%d", &n, &Q);
    for(int i = 2, x; i <= n; i++) scanf("%d", &x),add(x, i);
    for(int i = 1; i <= n; i++)
    scanf("%d%d", &B[i], &L[i]);
    dfs(1);
    build(1, n, 1);
    for(int i = 1, x; i <= Q; i++)
    {
        scanf("%d", &x);
        int ll = pos[x], rr = pos[x] + size[x] - 1;
        if (ll == rr){printf("0\n");continue;}
        SegmentTree Tree1 = query(1, ll - 1, 1) + query(rr + 1, n, 1);
        SegmentTree Tree2 = query(ll, rr, 1);
        if (Tree2.s > 1 && Tree1.lmx > 0) printf("%d\n", Tree2.bmx);
        else if (Tree2.bcx + Tree1.lmx > Tree2.bmx) printf("%d\n", Tree2.bmx);
        else if (Tree2.bcx + Tree1.lmx < Tree2.bmx) printf("%d\n", max(Tree2.bcx, Tree2.bcx + Tree1.lmx));
        else printf("%d\n", max(Tree2.bcx,max((int)(Tree2.bcx + Tree1.lcx), (int)(Tree2.bcc + Tree1.lmx))));
    }
}
View Code

T3题面

最水的一道,接近Dijkstra模板,考场时唯一需要想想的(判断是否符合条件)出错了 感谢良心数据

这样的放T3,结果我时间没安排好,都没多少时间仔细想,如果再多10分钟这样的题我一定过了qwq

技术分享图片
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n, m, p, k, w[205], q[205];
int G[205], dis[205][100005];
int tot = 0, Next[20005 << 1], to[20005 << 1], val[20005 << 1], head[20005 << 1], ok[20005 << 1];
bool vis[205][100005];
inline void add(int x,int y,int z, int kk)
{
    Next[++tot] = head[x];
    to[tot] = y;
    val[tot] = z;
    ok[tot] = kk;
    head[x] = tot;
}
struct rec{int x, w, cl;};
inline bool operator <(const rec &a, const rec &b)
{
    return a.w > b.w;
}
inline int Dijkstra(int s)
{
    priority_queue<rec>q;
    memset(vis, 0, sizeof vis);
    memset(dis, 63, sizeof dis);
    q.push((rec){s, 0, G[s]});
    dis[s][G[s]] = 0;
    int res = -1;
    while(!q.empty())
    {
        rec tmp = q.top();q.pop();
        if (vis[tmp.x][tmp.cl]) continue;
        vis[tmp.x][tmp.cl] = 1;
        if (tmp.x == n)
        if (res == -1) res = tmp.w;
        else res = min(res, tmp.w);
        for(int i = head[tmp.x]; i; i = Next[i])
        {
            if ((ok[i] & tmp.cl) == ok[i])
            {
                int V = to[i];
                if (dis[V][tmp.cl | G[V]] > (tmp.w + val[i]))
                dis[V][tmp.cl | G[V]] = tmp.w + val[i],
                q.push((rec){V, dis[V][tmp.cl | G[V]], tmp.cl | G[V]});
            }
        }
    }
    return res;
}
int main()
{
    memset(G, 0, sizeof G);
    scanf("%d%d%d%d", &n, &m, &p, &k);
    for(int i = 1; i <= k; i++)
    {
        scanf("%d%d", &w[i], &q[i]);
        for(int j = 1, x; j <= q[i]; j++)
        scanf("%d", &x),
        G[w[i]] |= (1 << (x - 1));
    }
    for(int i = 1, x, y, z, pp; i <= m; i++)
    {
        scanf("%d%d%d%d", &x, &y, &z, &pp);
        int kk = 0;
        for(int j = 1, xx; j <= pp; j++)
        {
            scanf("%d", &xx);
            kk |= (1 << (xx - 1));
        }
        add(y, x, z, kk);
        add(x, y, z, kk);
    }
    printf("%d\n", Dijkstra(1));
}
View Code

 

8.15模拟赛

标签:ring   ret   sig   font   ide   线段树   ble   一个   inline   

原文地址:https://www.cnblogs.com/gaojunonly1/p/9484139.html

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