TLE on #19 (请求Dalao救命, 大恩大德永世难忘 )
查看原帖
TLE on #19 (请求Dalao救命, 大恩大德永世难忘 )
239164
Meteorshower_Y楼主2022/8/12 20:47
#include<algorithm>
#include<iostream>
#include<climits>
#include<cstdio>
#include<stack>
#include<cmath>
#include<set>
#define ls(i) (i<<1)
#define rs(i) (i<<1|1)
using namespace std;
namespace fast_IO
{
    #define FAST_IO
    #define IOSIZE 100000
    typedef long long ll;
    typedef double db;
    typedef long double ldb;
    char ibuf[IOSIZE], obuf[IOSIZE];
    char *p1 = ibuf, *p2 = ibuf, *p3 = obuf;
    #ifdef ONLINE_JUDGE
    #define getchar() ((p1==p2)and(p2=(p1=ibuf)+fread(ibuf,1,IOSIZE,stdin),p1==p2)?(EOF):(*p1++))
    #define putchar(x) ((p3==obuf+IOSIZE)&&(fwrite(obuf,p3-obuf,1,stdout),p3=obuf),*p3++=x)
    #endif

    #define isdigit(ch) (ch>47&&ch<58)
    #define isspace(ch) (ch<33&&ch!=EOF)
    
    struct fast_IO_t {
        ~fast_IO_t() {
            fwrite(obuf, p3-obuf, 1, stdout);
        }
        bool flag = false;
        operator bool() {
            return flag;
        }
    }io;
    
    template<typename T> inline T read() {
        T s = 0; int w = 1; char ch;
        while(ch=getchar(), !isdigit(ch)&&(ch!=EOF))
            if(ch == '-') w = -1;
        if(ch == EOF) return 0;
        while(isdigit(ch))
            s = s*10+ch-48, ch=getchar();
        if(ch == '.') {
            ll flt = 0; int cnt = 0;
            while(ch=getchar(), isdigit(ch))
                if(cnt < 18) flt=flt*10+ch-48, cnt++;
            s += (db)flt/pow(10,cnt);
        }
        return s *= w;
    }
    template<typename T> inline bool read(T &s) {
        s = 0; int w = 1; char ch;
        while(ch=getchar(), !isdigit(ch)&&(ch!=EOF))
            if(ch == '-') w = -1;
        if(ch == EOF) return false;
        while(isdigit(ch))
            s = s*10+ch-48, ch=getchar();
        if(ch == '.') {
            ll flt = 0; int cnt = 0;
            while(ch=getchar(), isdigit(ch))
                if(cnt < 18) flt=flt*10+ch-48, cnt++;
            s += (db)flt/pow(10,cnt);
        }
        return s *= w, true;
    }
    inline bool read(char &s) {
        while(s = getchar(), isspace(s));
        return s != EOF;
    }
    inline bool read(char *s) {
        char ch;
        while(ch=getchar(), isspace(ch));
        if(ch == EOF) return false;
        while(!isspace(ch))
            *s++ = ch, ch=getchar();
        *s = '\000';
        return true;
    } 
    template<typename T> void print(T x) {
        static int t[20]; int top = 0;
        if(x < 0) putchar('-'), x = -x;
        do { t[++top] = x%10; x /= 10; } while(x);
        while(top) putchar(t[top--]+48);
    }
    struct empty_type{}; int pcs = 8;
    empty_type setpcs(int cnt) {
        return pcs = cnt, empty_type();
    }
    inline void print(empty_type x){}
    inline void print(double x) {
        if(x < 0) putchar('-'), x = -x;
        x += 5.0 / pow(10,pcs+1);
        print((ll)(x)); x -= (ll)(x);
        if(pcs != 0) putchar('.');
        for(int i = 1; i <= pcs; i++)
        x *= 10, putchar((int)x+'0'), x -= (int)x;
    }
    inline void print(float x) {
        if(x < 0) putchar('-'), x = -x;
        x += 5.0 / pow(10,pcs+1);
        print((ll)(x)); x -= (ll)(x);
        if(pcs != 0) putchar('.');
        for(int i = 1; i <= pcs; i++)
        x *= 10, putchar((int)x+'0'), x -= (int)x;
    }
    inline void print(char x) {
        putchar(x);
    }
    inline void print(char *x) {
        for(int i = 0; x[i]; i++)
            putchar(x[i]);
    }
    inline void print(const char *x) {
        for(int i = 0; x[i]; i++)
            putchar(x[i]);
    }
    #ifdef _GLIBCXX_STRING//string
        inline bool read(std::string& s) {
            s = ""; char ch;
            while(ch=getchar(), isspace(ch));
            if(ch == EOF) return false;
            while(!isspace(ch))
                s += ch, ch = getchar();
            return true;
        }
        inline void print(std::string x) {
            for(string::iterator i = x.begin(); i != x.end(); i++)
                putchar(*i);
        }
        inline bool getline(fast_IO_t &io, string s) {
            s = ""; char ch = getchar();
            if(ch == EOF) return false;
            while(ch != '\n' and ch != EOF)
                s += ch, ch = getchar();
            return true;
        }
    #endif
    #if __cplusplus >= 201103L
        template<typename T, typename... T1>
        inline int read(T& a, T1& ...other) {
            return read(a)+read(other...);
        }
        template<typename T, typename... T1>
        inline void print(T a, T1... other) {
            print(a); print(other...);
        }
    #endif
    template<typename T>
    fast_IO_t& operator >> (fast_IO_t &io, T &b) {
        return io.flag=read(b), io;
    }
    fast_IO_t& operator >> (fast_IO_t &io, char *b) {
        return io.flag=read(b), io;
    }
    template<typename T>
    fast_IO_t& operator << (fast_IO_t &io, T b) {
        return print(b), io;
    }
    #define cout io
    #define cin io
    #define endl '\n'
}
using namespace fast_IO;
const int MAXN = 4e5+10;
const int MAXM = 4e5+10;
const int inf = INT_MAX;
multiset<int> cost[MAXM];
struct edge {int from, to;int next;};
struct tree {int l, r; int val;};
namespace Tarjan
{
    edge a[MAXN<<1];
    stack<int> st; int w[MAXN<<1];
    int head[MAXN], cnt, tot, all;
    int dfn[MAXN], low[MAXN], tim;
    auto tarjan(int x) -> void;
    auto add_edge(int from, int to) -> void;
}
namespace Tree
{
    edge a[MAXM<<1];
    tree tr[MAXM<<2];
    int f[MAXM], siz[MAXM], son[MAXM];
    int id[MAXM], top[MAXM], dep[MAXM];
    int head[MAXM], aid[MAXM], cnt, tim;
    auto add_edge(int from, int to) -> void;
    auto dfs1(int x, int fa) -> void;
    auto dfs2(int x, int tp) -> void;
    auto query(int l, int r, int i) -> int;
    auto build(int l, int r, int i) -> void;
    auto change_r(int x, int k, int i) -> void;
    auto change_s(int x, int k, int i) -> void;
    auto query_min(int x, int y) -> void;
    auto change_val(int x, int k) -> void;
}
int n, m, q, u, v, c[MAXN]; char op;
int main()
{
    read(n, m, q);
    for(int i = 1; i <= n; i += 1) read(c[i]);
    for(int i = 1; i <= m; i += 1)
    {
        read(u, v);
        Tarjan::add_edge(u, v);
        Tarjan::add_edge(v, u);
    }
    Tarjan::tot = n;
    Tarjan::tarjan(1);
    Tree::dfs1(1, 0);
    Tree::dfs2(1, 1);
    Tree::build(1, Tarjan::tot, 1);
    for(int i = 1; i <= q; i += 1)
    {
        cin >> op >> u >> v;
        if(op == 'A') Tree::query_min(u, v);
        else Tree::change_val(u, v);
    }
    return 0;
}

namespace Tarjan
{
    auto add_edge(int from, int to) -> void
    {
        cnt += 1;
        a[cnt].from = from;
        a[cnt].to = to;
        a[cnt].next = head[from];
        head[from] = cnt;
    }
    auto tarjan(int x) -> void
    {
        dfn[x] = low[x] = ++tim;
        st.push(x); all += 1; 
        w[x] = c[x]; int y, z;
        for(int i = head[x]; i; i = a[i].next)
        {
            y = a[i].to;
            if(!dfn[y]) 
            {
                tarjan(y);
                low[x] = min(low[x], low[y]);
                if(low[y] == dfn[x]) 
                {
                    w[++tot] = INT_MAX;
                    while((z = st.top()))
                    {
                        st.pop(); 
                        Tree::add_edge(z, tot);
                        Tree::add_edge(tot, z);
                        if(z == y) break;
                    }
                    Tree::add_edge(x, tot);
                    Tree::add_edge(tot, x);
                }
            }
            else low[x] = min(low[x], dfn[y]);
        }
    }
}

namespace Tree
{
    auto add_edge(int from, int to) -> void
    {
        cnt += 1;
        a[cnt].from = from;
        a[cnt].to = to;
        a[cnt].next = head[from];
        head[from] = cnt;
    }
    auto dfs1(int x, int fa) -> void
    {
        f[x] = fa; siz[x] = 1;
        dep[x] = dep[f[x]]+1;
        int maxson = 0, y;
        for(int i = head[x]; i; i = a[i].next)
        {
            y = a[i].to; if(y == fa) continue;
            dfs1(y, x); siz[x] += siz[y];
            if(siz[y] > siz[maxson]) maxson = y;
        }
        if(x > n)
        {
            for(int i = head[x]; i; i = a[i].next)
            {
                y = a[i].to; if(y == fa) continue;
                Tarjan::w[x] = min(Tarjan::w[x], Tarjan::w[y]);
                cost[x].insert(Tarjan::w[y]);
            }
        }
        son[x] = maxson;
    }
    auto dfs2(int x, int tp) -> void
    {
        id[x] = ++tim; aid[tim] = x;
        top[x] = tp; int y;
        if(son[x]) dfs2(son[x], tp);    
        for(int i = head[x]; i; i = a[i].next)
        {
            y = a[i].to;
            if(y == f[x] or y == son[x]) continue;
            dfs2(y, y);
        }
    }
    auto build(int l, int r, int i) -> void
    {
        tr[i].l = l;
        tr[i].r = r;
        if(l == r) return (void)(tr[i].val = Tarjan::w[aid[l]]);
        int mid = (l+r)>>1;
        build(l, mid, ls(i));
        build(mid+1, r, rs(i));
        tr[i].val = min(tr[ls(i)].val, tr[rs(i)].val);
    }
    auto change_r(int x, int k, int i) -> void
    {
        if(tr[i].l > x or tr[i].r < x) return ;
        if(tr[i].l == x and tr[i].r == x) return (void)(tr[i].val = k);
        change_r(x, k, ls(i));
        change_r(x, k, rs(i));
        tr[i].val = min(tr[ls(i)].val, tr[rs(i)].val);
    }
    auto change_s(int x, int k, int i) -> void
    {
        if(tr[i].l > x or tr[i].r < x) return ;
        if(tr[i].l == x and tr[i].r == x) return (void)(tr[i].val = k);
        change_s(x, k, ls(i));
        change_s(x, k, rs(i));
        tr[i].val = min(tr[ls(i)].val, tr[rs(i)].val);
    }
    auto query(int l, int r, int i) -> int
    {
        if(tr[i].l > r or tr[i].r < l) return inf;
        if(tr[i].l >= l and tr[i].r <= r) return tr[i].val;
        return min(query(l, r, ls(i)), query(l, r, rs(i)));
    }
    auto query_min(int x, int y) -> void
    {
        int ans = inf;
        while(top[x] != top[y])
        {
            if(dep[top[x]] < dep[top[y]]) swap(x, y);
            ans = min(ans, query(id[top[x]], id[x], 1));
            x = f[top[x]];
        }
        if(id[x] > id[y]) swap(x, y);
        ans = min(ans, query(id[x], id[y], 1));
        if(x > n) ans = min(ans, query(id[f[x]], id[f[x]], 1));
        print(ans, '\n');
    }
    auto change_val(int x, int k) -> void
    {
        change_r(id[x], k, 1);
        int y = f[x];
        multiset<int>::iterator iter = lower_bound(cost[y].begin(), cost[y].end(), Tarjan::w[x]);
        Tarjan::w[x] = k;
        if(x == 1 or iter == cost[y].end()) return ;
        cost[y].erase(iter); 
        cost[y].insert(k);
        
        change_s(id[y], *(cost[y].begin()), 1);
    }
}

2022/8/12 20:47
加载中...