首页 > 其他分享 >ABC350题解(E-G)

ABC350题解(E-G)

时间:2024-04-20 21:59:04浏览次数:18  
标签:node return int 题解 void splay ABC350 NULL

E

直接搜一下 \(N\) 的可能到达的值的个数,发现不多(大约 \(10^4\) 个),直接暴力 dp(记忆化搜索)。

转移式 \(f_i=\max(X \log_{A}N,\dfrac{\sum\limits_{j=1}^6f_{i/j}}{6}+Y)\)。

化简得到 \(f_i=\max(X \log_{A}N,\dfrac{\left(\sum\limits_{j=2}^6f_{i/j}\right)+6Y}{5})\)。

F

文艺平衡树直接区间翻转 \(O(n\log n)\),然后大小写离线下来扫一遍就行了,总复杂度 \(O(n\log n)\)。

G

lct 板子题。

\(1\ u\ v\) 操作即 lct 的 link(u,v)

\(2\ u\ v\) 操作考虑先 makeroot(u) 把 \(u\) 放到根节点,然后 access(v),然后 \(v\) 向上跳两步(找父亲即 splay 的获得前驱操作)看一下是不是 \(u\) 就行了。

代码

E

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

#define int ll

set<int> s;
map<int, int> pos, val;
void dfs(int x)
{
    if(!x || s.count(x)) return;
    s.insert(x);
    for(int i = 2; i <= 6; i ++) dfs(x / i);
}

const int N = 1e5;
long double f[N];
int n, a, x, y;

int logA(int x)
{
    int ans = 1; __int128 r = 1;
    while(r <= x) ans ++, r *= a;
    return ans - 1;
}

signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    cin >> n >> a >> x >> y;
    dfs(n);
    int c = 0;
    for(int i : s) c ++, pos[i] = c, val[c] = i;
    pos[0] = 0;
    for(int i = 1; i <= c; i ++)
    {
        long double s = 0;
        for(int j = 2; j <= 6; j ++)
            s += f[pos[val[i] / j]] / 6;
        f[i] = min(1.L * x * logA(val[i]), (s + y) * 6.L / 5.L);
        // cerr << i << " " << val[i] << " " << f[i] << endl;
    }
    printf("%.15Lf", f[c]);

    return 0;
}

F

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N = 5e5 + 5;

struct node
{
    int v, tag, sz;
    node *s[2], *p;
    void init(node *_p, int _v)
    {
        sz = 1, v = _v, p = _p;
    }
    void swp() {swap(s[0], s[1]);}
    void pd()
    {
        if(!tag) return;
        swp();
        if(s[0]) s[0]->tag ^= 1;
        if(s[1]) s[1]->tag ^= 1;
        tag = 0;
    }
    void pu() {sz = (s[0] ? s[0]->sz : 0) + (s[1] ? s[1]->sz : 0) + 1;}
}a[N], *root;

int idx = 0;

void rotate(node *x)
{
    if(x->p == NULL) return;
    node *y = x->p, *z = y->p;
    int k = y->s[1] == x;
    x->p = z;
    if(z) z->s[z->s[1] == y] = x;
    y->s[k] = x->s[k ^ 1];
    if(x->s[k ^ 1]) x->s[k ^ 1]->p = y;
    y->p = x, x->s[k ^ 1] = y;
    y->pu();x->pu();
}

void pushd(node *x) {if(x == NULL) return; pushd(x->p); x->pd();}

void splay(node *x, node *k)
{
    if(x == NULL) assert(a[0].p->v);
    pushd(x);
    while(x->p != k)
    {
        node *y = x->p, *z = y->p;
        if(z != k)
            if((y->s[1] == x) ^ (z->s[1] == y)) rotate(x);
            else rotate(y);
        rotate(x);
    }
    if(k == NULL) root = x;
}

node* find(int x)
{
    node *u = root;
    while(u != NULL)
    {
        u->pd();
        if(u->s[0] && u->s[0]->sz >= x) u = u->s[0];
        else if((u->s[0] ? u->s[0]->sz : 0) + 1 == x) return splay(u, NULL), u;
        else x -= (u->s[0] ? u->s[0]->sz : 0) + 1, u = u->s[1];
    }
    return NULL;
}

void rev(int l, int r)
{
    node *xl = find(l), *xr = find(r + 2); // [l + 1, r + 1]
    splay(xl, NULL);splay(xr, xl);
    xr->s[0]->tag ^= 1;
    splay(xr->s[0], NULL);
}

node* insert(node *x, int v)
{
    splay(x, NULL);
    x->s[1] = &a[++idx];
    a[idx].init(x, v);
    splay(&a[idx], NULL);
    return &a[idx];
}

int n, ans[N], nown;

void print(node *x)
{
    if(x == NULL) return;
    x->pd();
    print(x->s[0]);
    if(x->v) nown ++, ans[nown] = x->v;
    print(x->s[1]);
}

string s;
vector<pair<int, int>> pr;

void read()
{
    string s0; cin >> s0;
    stack<int> stk;
    int nowu = 0;
    for(char c : s0)
    {
        if(c == '(')
        {
            nowu ^= 1;
            stk.push(s.size() + 1);
        }
        else if(c == ')')
        {
            nowu ^= 1;
            pr.push_back({stk.top(), (int)s.size()});
            stk.pop();
        }
        else
        {
            if(nowu)
            {
                if(c >= 'A' && c <= 'Z') s += (c - 'A' + 'a');
                else s += (c - 'a' + 'A');
            }
            else s += c;
        }
    }
    n = s.size();
}

signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    read();
    idx = 1;a[1].init(NULL, 0);root = &a[1];
    node* lst = &a[1];
    for(int i = 1; i <= n; i ++)
        lst = insert(lst, i);
    insert(lst, 0);
    for(auto o : pr)
    {
        int l = o.first, r = o.second;
        if(l > r) continue;
        rev(l, r);
    }
    print(root);
    for(int i = 1; i <= n; i ++)
    {
        cout << s[ans[i] - 1];
    }

    return 0;
}

G

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

#define int ll

const int N = 1e5 + 5;
struct node {int p, s[2], v, w, tg;} a[N];

bool isr(int x) {return a[a[x].p].s[0] != x && a[a[x].p].s[1] != x;}

void pu(int x) {a[x].w = a[a[x].s[0]].w ^ a[a[x].s[1]].w ^ a[x].v;} // v, w

void pd(int x) {if(a[x].tg) {swap(a[x].s[0], a[x].s[1]); if(a[x].s[0]) a[a[x].s[0]].tg ^= 1; if(a[x].s[1]) a[a[x].s[1]].tg ^= 1; a[x].tg = 0;}}

void pdp(int x) {if(!isr(x)) pdp(a[x].p); pd(x);}

void rotate(int x)
{
    int y = a[x].p, z = a[y].p;
    int k = a[y].s[1] == x;
    if(!isr(y)) a[z].s[a[z].s[1] == y] = x;
    a[x].p = z;
    a[y].s[k] = a[x].s[k ^ 1], a[a[x].s[k ^ 1]].p = y;
    a[x].s[k ^ 1] = y, a[y].p = x;
    pu(y); pu(x);
}

void splay(int x)
{
    pdp(x);
    while(!isr(x))
    {
        int y = a[x].p, z = a[y].p;
        if(!isr(y))
            if((a[z].s[1] == y) ^ (a[y].s[1] == x)) rotate(x);
            else rotate(y);
        rotate(x);
    }
}

int pre(int x)
{
    splay(x); pd(x);
    if(!a[x].s[0]) return 0;
    int u = a[x].s[0];
    while(pd(u), a[u].s[1]) u = a[u].s[1];
    splay(u); return u;
}

void access(int x)
{
    int lst = 0;
    while(x) splay(x), a[x].s[1] = lst, pu(x), lst = x, x = a[x].p;
}

void mkrt(int x) {access(x); splay(x); a[x].tg ^= 1;}

int findrt(int x) {access(x); splay(x); while(pd(x), a[x].s[0]) x = a[x].s[0]; return splay(x), x;} // pushdown

void link(int x, int y) {mkrt(x); if(findrt(y) == x) return; a[x].p = y;}

int getf(int x)
{
    access(x);
    return pre(x);
}

int qry(int x, int y) {mkrt(x); access(y); splay(x); return a[x].w;}

signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    int n, q; cin >> n >> q;
    int lans = 0;
    while(q --)
    {
        int op, x, y; cin >> op >> x >> y;
        op = 1 + ((op * (1 + lans) % 998244353) % 2);
        x = 1 + ((x * (1 + lans) % 998244353) % n);
        y = 1 + ((y * (1 + lans) % 998244353) % n);
        if(op == 1)
        {
            link(x, y);
        }
        else
        {
            mkrt(x);
            if(findrt(y) != x) {lans = 0; cout << 0 << "\n";}
            else
            {
                int fy = getf(y);
                if(!fy) {lans = 0; cout << 0 << "\n";}
                else
                {
                    int ffy = getf(fy);
                    if(ffy != x) {lans = 0; cout << 0 << "\n";}
                    else lans = fy, cout << fy << "\n";
                }
            }
        }
    }

    return 0;
}

后记

好像 F 做法有点唐。。这下成暴力大师了。。

标签:node,return,int,题解,void,splay,ABC350,NULL
From: https://www.cnblogs.com/adam01/p/18148235

相关文章

  • 荒岛野人 题解
    Statement有\(n(\le15)\)个野人,第\(i\)个野人的寿命是\(L_i(\le10^6)\)年。荒岛上有\(m\)个山洞排列成一个环,但你不知道\(m\)到底是多少。第\(i\)个野人第一年会从第一个山洞开始往后数\(C_i\)个住下来,此后每一年都会往后数\(P_i\)个山洞住下来。已知不会发生某......
  • 双模数问题 题解
    Statement\(S(n,m)=\{k\midk\in\mathbbN^+\landn\bmodk+m\bmodk\gek\}\),求\(\varphi(n)\varphi(m)\sum_{k\inS(n,m)}k\pmod{998244353}\)(\(n,m\le10^{15}\))Solution欧拉函数怎么求就不说了,可以\(\mathcalO(\sqrtn)\)解决\(n\bmodk+m\bmodk......
  • [HEOI2014]大工程 题解
    发现可以直接建立虚树。设\(dp_{u,0/1/2}\)表示第\(u\)个节点的子树内,所有选中节点到它的距离之和/选中节点中到它的最短距离/选中节点中到它的最长距离,\(as_{u,0/1/2}\)则代表对于这个子树,题目所问问题的三个答案,\(i1,i2\)分别为使\(dp_{u,1/2}\)取极值的\(v\)。则\(......
  • [题解] [洛谷 P1174] 打砖块
    [洛谷P1174]打砖块题目描述有\(n\)行\(m\)列的砖块和\(k\)发子弹,每个砖块都有一个得分,每次可以用一发子弹打碎某一列最下面的砖块并得到相应的得分。有的砖块在打碎后可以获得一发额外子弹的奖励。求该游戏的最大得分。输入格式第一行有\(3\)个正整数,\(n,m,k\)。......
  • [题解] [洛谷 P1174] 打砖块
    [洛谷P1174]打砖块题目描述有\(n\)行\(m\)列的砖块和\(k\)发子弹,每个砖块都有一个得分,每次可以用一发子弹打碎某一列最下面的砖块并得到相应的得分。有的砖块在打碎后可以获得一发额外子弹的奖励。求该游戏的最大得分。输入格式第一行有\(3\)个正整数,\(n,m,k\)。......
  • newstartweek3部分题解
    64位利用格式化字符串修改got表例题:newstartweek3putorsystem老规矩先checksec和代码审计:看到开了canary和NX(但是对于这道题的话canary是没有用的),然后源码这边也没有发现有system函数,也没有后门函数,所以我们需要自己在libc里面找,然后就有bin/sh那么我们就只用把got表里......
  • [BZOJ3037] 创世纪 题解
    基环内向树上dp,不过在这里提供给一种非典型做法。考虑将环上的每一条边都断开,这样就会形成多棵树,先在这些树上进行树形\(dp\)。设\(dp_{i,0/1}\)表示不选/选\(i\)时,\(i\)子树内的最大选点数。明显方程为:\[\begin{cases}dp_{u,0}=\sum\limits_{v\inuson}\max(dp_{v,0},dp......
  • [题解]ABC209F Deforestation
    ABC209FDeforestation首先我们可以思考\(a_i\)和\(a_{i+1}\)先砍哪棵花费少。可以看出,当\(a[i]<a[i+1]\)时,先砍\(a[i+1]\),反之亦然。所以这个题转化成了:给定\(n-1\)个关系,分别表示\(n\)个值中相邻两个的大小关系,问满足这些关系的序列个数。与AtcoderEducationalDPContest......
  • φ(* ̄0 ̄)3337. poj1845 sumdiv题解
    遇到数论题就要推式子!提供最美丽的latex\[a^b=p_1^{a_1*b}*p_2^{a_2*b}*p_3^{a_3*b}......*p_n^{a_n*b}\\那么他的因数之和为:\\({p_1}^0+{p_1}^1+...+{p_1}^{a_1*b})\\*({p_2}^0+{p_2}^1+...+{p_2}^{a_2*b})\\...\\*({p_n}^0+{p_n}^1+...+{p_n}^{a_n*b})\\=>利用等......
  • 「NOIP2012」同余方程 题解!!
    嗨嗨嗨!又是我想写这道题,我们就需要掌握:拓展欧几里得顾名思义,它就是欧几里得算法(人话:辗转相除法)的proMax版本别告诉我你不会辗转相除法拓展欧几里得的作用是求对于方程\[a*x+b*y=gcd(a,b)\]解出x,y的值。让我们一步步分析!贴个辗转相除板子先:voidojld(inta,intb){ i......