玄学卡常(违规删)
查看原帖
玄学卡常(违规删)
218172
BiaxialRay楼主2025/1/27 21:31

以下这段代码最后6个测试点运行时间正好在1s左右,会随机TLE或AC,最后抽奖过的(

#include<cstdio>
#include<cmath>
#include<map>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
#include<string>
#include<iostream>
#include<cstring>
using namespace std;
const int Maxn = 4e5+5,Maxm = 4e5+5;
#define ll long long
#define ull unsigned long long
const ll INF= (ll)1e17 + 5LL;
const ll Mod = 998244353;
const double eps = 1e-8;
// ll Mod;
int n,m,h,r,Cnt,q,Cnt0,Cnt1;
int x,y;
int vis[Maxm];
int head[Maxn],indeg[Maxn],outdeg[Maxn],deg[Maxn],suf[Maxn],pre[Maxn],L[Maxn],R[Maxn];
// int minx[1005][10][10];
ll num[Maxn],num0[Maxn],ans1[Maxn],ans2[Maxn],num1[Maxn];
// int dp[15][15*15],num0[Maxn],head1[Maxn],vis[Maxn],anc[Maxn][25],sum[Maxn],pre1[Maxn],P[Maxn],indeg1[Maxn];
ll tot;
char str[Maxn],str1[Maxn],result[Maxn];
int dirx[] = {1,-1,0,0},diry[] = {0,0,1,-1};
// vector<ll> num1(20,0);
// vector<ll> num2(20,0);
// vector<pair<int,int>> res(Maxn);

ll myabs(ll x){
    return x > 0 ? x : -x;
}

struct Side{
    int s;
    int e;
    ll w;
    // ll w1;
    // int cnt;
    int next;
}side[Maxm];

// ll fact(ll x){
//     if(x <= 1)return 1;
//     return x * fact(x-1);
// }

// ll C(ll m,ll n){
//     if(m > n)return 0LL;
//     return fact(n)/(fact(m))/fact(n-m);
// }

void add(int s,int e){
    ++Cnt;
    // ++indeg[e];
    side[Cnt].s = s;
    side[Cnt].e = e;
    // side[Cnt].w = w;
    // side[Cnt].w1 = 0;
    // side[Cnt].cnt = 0;
    side[Cnt].next = head[s];
    head[s] = Cnt;
}

ll M(ll x){
    return ((x % Mod) + Mod) % Mod;
}

ll max(ll x,ll y){
    return x > y ? x : y;
}

ll sgn(ll x){
    if(x >= 0)return 1;
    else return -1;
}

ll min(ll x,ll y){
    return x < y ? x : y;
}

ll gcd(ll x,ll y){
    return y ? gcd(y,x%y) : x;
}

ll ex_gcd(ll a,ll b,ll &x,ll &y){
    if(b == 0){
        x = 1;
        y = 0;
        return a;
    }
    ll d;
    d = ex_gcd(b,a % b,y,x);
    y = M(y - a / b * x);
    return d;
}

ll Inverse(ll p,ll q){
    ll x,y;
    ex_gcd(q,Mod,x,y);
    return M(M(x) * M(p));
}

ll fact(ll x){
    if(x <= 1)return 1;
    return x * fact(x-1) % Mod;
}

// ll C(ll m,ll n){
//     if(m > n)return 0LL;
//     return Inverse(fact(n),fact(m)*fact(n-m) % Mod);
// }

ll lcm(ll x,ll y){
    return x * y / gcd(x,y);
}

int count_bit(int x){
    int res = 0;
    while(x){
        ++res;
        x >>= 1;
    }
    return res;
}

ll quick_pow(ll x,ll y){
    ll res = 1,unit = x;
    while(y){
        if(y & 1LL)res = res * unit % Mod;
        unit = unit * unit % Mod;
        y >>= 1LL;
    }
    return res;
}

int highbit(int x){
    if(x == 0)return 0;
    int res = 1;
    while(x > 1){
        x >>= 1;
        res <<= 1;
    }
    return res;
}

int lowbit(int x){
    return x & (-x);
}

void swap(int &x,int &y){
    int tmp = x;
    x = y;
    y = tmp;
}

int count1(int x){
    int cnt = 0;
    while(x){
        cnt += (x & 1);
        x >>= 1;
    }
    return cnt;
}

struct Node{
    ll x;
    int idx;
    int operator<(const Node &w) const &{
        return x < w.x;
    }
}cur,N[Maxn],N0[Maxn],cur1;

// struct Node1{
//     int x;
//     int idx;
//     int operator < (const Node1 &w) const &{
//         if(x == w.x)return idx < w.idx;
//         return x < w.x;
//     }
// }cur;

// ll getnum(){
//     ll res = 0,f = 1;
//     char ch;
//     while(1){
//         ch = getchar();
//         if(ch == '-')f *= -1;
//         if(!(ch >= '0' && ch <= '9'))continue;
//         else break;
//     }
//     res = res * 10 + ch - '0';
//     while(1){
//         ch = getchar();
//         if(!(ch >= '0' && ch <= '9'))break;
//         res = res * 10 + ch - '0';
//     }
//     return res * f;
// }

// void putnum(ll x){
//     if(x == 0)putchar('0');
//     stack<char> S;
//     while(x){
//         S.push('0' + (x % 10));
//         x /= 10;
//     }
//     while(!S.empty()){
//         putchar(S.top());
//         S.pop();
//     }
// }



ll sum[Maxn],res[Maxn],prex[Maxn],value[Maxn],dfn[Maxn],low[Maxn],ct[Maxn],order[Maxn],prem[Maxn],sufm[Maxn],recover[Maxn];
ll TIME;

int dfs1(int x){
    int cnt = 1,i;
    vis[x] = 1;
    for(i = head[x];i;i = side[i].next){
        if(vis[side[i].e])continue;
        cnt += dfs1(side[i].e);
    }
    return ct[x] = cnt;
}

void dfs2(int x){
    int i;
    ++TIME;
    order[TIME] = num[x];
    recover[TIME] = x;
    vis[x] = 1;
    dfn[TIME] = TIME;
    low[TIME] = dfn[TIME] + ct[x] - 1;
    for(i = head[x];i;i = side[i].next){
        if(vis[side[i].e])continue;
        dfs2(side[i].e);
    }
}

int main(){
    int i,j,k,v,w;
    // ll x0,y0,k;
    char ch;
    ll tmp,tot,unit;
    int tmp1,tmp2,tmp3,tmp4;
    
    int _;
    _ = 1;
    // scanf("%d",&_);
    int idx = 0;
    while(_--){
        scanf("%d",&n);
        vector<vector<ll>> minx(n+5,vector<ll>(40,0)),to(n+5,vector<ll>(40,0));
        vector<vector<ll>> sum(n+5,vector<ll>(40,0));
        vector<vector<ll>> sufm(n+5,vector<ll>(40,1e15));
        for(i = 2;i <= n;++i){
            scanf("%d",&num[i]);
            minx[i][0] = num[i];
            to[i][0] = num[i];
        }
        // for(i = 1;i <= 25;++i){
        //     if((1 << i) > n)break;
        //     for(j = 1;j + (1<<i)-1 <= n;++j){
        //         minx[j][i] = min(minx[j][i-1],minx[j+(1<<(i-1))][i-1]);
        //     }
        // }
        for(i = 1;i <= 18;++i){
            for(j = n;j >= 1;--j){
                sufm[j][i-1] = min(sufm[j+1][i-1],to[j][i-1]);
            }
            sufm[0][i-1] = 0;
            for(j = n;j >= 1;--j){
                to[j][i] = sufm[to[j][i-1]][i-1];
            }
        }
        for(i = 1;i <= n;++i){
            sum[i][0] = i - sufm[i][0];
            for(j = 1;j <= 18;++j){
                sum[i][j] = sum[i][j-1] + (sufm[i][j-1]-sufm[i][j]) * (1LL << (j-1)) + sum[sufm[i][j-1]][j-1];
            }
        }
        int q;
        scanf("%d",&q);
        while(q--){
            ll ans = 0,now = 1,l,r;
            scanf("%d %d %d",&tmp1,&tmp2,&tmp3);
            tmp2++;
            ll res1,res2;
            if(tmp1 >= num[tmp3]){
                res1 = (tmp3 - tmp1);
            }else{
                res1 = (tmp3 - num[tmp3]);
                int now = num[tmp3],unit = 1;
                for(i = 17;i >= 0;--i){
                    if(sufm[now][i] <= tmp1)continue;
                    res1 += (now - sufm[now][i]) * unit + sum[now][i];
                    unit += (1 << i);
                    now = sufm[now][i];
                }
                res1 += (now - tmp1) * (unit + 1);
            }
            if(tmp2 >= num[tmp3]){
                res2 = (tmp3 - tmp2);
            }else{
                res2 = (tmp3 - num[tmp3]);
                int now = num[tmp3],unit = 1;
                for(i = 17;i >= 0;--i){
                    if(sufm[now][i] <= tmp2)continue;
                    res2 += (now - sufm[now][i]) * unit + sum[now][i];
                    unit += (1 << i);
                    now = sufm[now][i];
                }
                res2 += (now - tmp2) * (unit + 1);
            }
            // printf("ans:%lld %lld\n",res1,res2);
            ll res = gcd(res1-res2,tmp2-tmp1);
            printf("%lld/%lld\n",(res1-res2)/res,(tmp2-tmp1)/res);
        }
    }       

    scanf("%d %d",&n,&k);
    return 0;
}
2025/1/27 21:31
加载中...