[NOI2018]歸程

description

題面html

data range

\[ n\le 200000,m,k\le 400000\]node

solution

\(Kruskal\)重構樹ios

甚至比[ONTAK2010]Peaks增強版還要容易碼c++

再也不多說函數

code

爲何我寫了個叫\(Dij\)的函數,一開始寫的倒是\(SPFA\)...spa

習慣很難改啊code

#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<complex>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<ctime>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define FILE "a"
#define mp make_pair
#define pb push_back
#define RG register
#define il inline
using namespace std;
typedef unsigned long long ull;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
const dd eps=1e-10;
const int mod=1e9+7;
const int N=400010;
const int M=400010;
const dd pi=acos(-1);
const int inf=2147483645;
const ll INF=1e18+1;
const ll P=100000;
il ll read(){
    RG ll data=0,w=1;RG char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')w=-1,ch=getchar();
    while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
    return data*w;
}

il void file(){
    srand(time(NULL)+rand());
    freopen("1.in","r",stdin);
    freopen(FILE".out","w",stdout);
}

int num,n,m,q,k,s,ans;
struct edge{int u,v,w;}E[M];
bool cmp_w(edge x,edge y){return x.w>y.w;}
int head[N],to[N<<1],nxt[N<<1],val[N<<1],cnt;
il void add(int u,int v,int w){
    to[++cnt]=v;
    nxt[cnt]=head[u];
    val[cnt]=w;
    head[u]=cnt;
}

struct node{
    int id,x;
    bool operator <(const node &b)const{return x>b.x;}
};
priority_queue<node>Q;
int dis[N];bool vis[N];
il void Dijaaaaaaaaaaaaaaa(){
    for(RG int i=1;i<=n;i++)dis[i]=inf,vis[i]=0;
    while(!Q.empty())Q.pop();
    dis[1]=0;Q.push((node){1,0});
    for(RG int t=1;t<=n;t++){
        RG node x=Q.top();Q.pop();
        while(vis[x.id]){
            if(Q.empty())break;
            x=Q.top();Q.pop();
        }
        if(vis[x.id]&&Q.empty())break;
        RG int u=x.id;vis[u]=1;
        for(RG int i=head[u];i;i=nxt[i]){
            RG int v=to[i];
            if(!vis[v]&&dis[v]>dis[u]+val[i]){
                dis[v]=dis[u]+val[i];Q.push((node){v,dis[v]});
            }
        }
    }
}

int fa[N];
int find(int x){return fa[x]?fa[x]=find(fa[x]):x;}

int h[N],RT,f[20][N];
void dfs(int u,int ff){
    f[0][u]=ff;
    for(RG int i=1;f[i-1][f[i-1][u]];i++)f[i][u]=f[i-1][f[i-1][u]];
    for(RG int i=head[u];i;i=nxt[i]){
        RG int v=to[i];dfs(v,u);
    }
}

il int solve(int v,int p){
    RG int u=v;
    for(RG int i=19;~i;i--)
        if(f[i][u]&&h[f[i][u]]>p)u=f[i][u];
    return dis[u];
}

int main()
{
    RG int T=read();
    while(T--){
        memset(head,0,sizeof(head));
        memset(fa,0,sizeof(fa));
        memset(f,0,sizeof(f));
        cnt=ans=0;
        
        num=n=read();m=read();
        for(RG int i=1,u,v,l,a;i<=m;i++){
            u=read();v=read();l=read();a=read();
            E[i]=(edge){u,v,a};
            add(u,v,l);add(v,u,l);
        }
        
        Dijaaaaaaaaaaaaaaa();
        
        memset(head,0,sizeof(head));cnt=0;
        sort(E+1,E+m+1,cmp_w);
        for(RG int i=1;i<=m;i++)
            if(find(E[i].u)!=find(E[i].v)){
                RG int x=find(E[i].u),y=find(E[i].v);
                h[++num]=E[i].w;
                fa[x]=fa[y]=num;dis[num]=min(dis[x],dis[y]);
                add(num,x,0);add(num,y,0);
            }
        RT=find(1);dfs(RT,0);

        q=read();k=read();s=read();
        for(RG int i=1,v,p;i<=q;i++){
            v=(read()+k*ans-1)%n+1;
            p=(read()+k*ans)%(s+1);
            printf("%d\n",ans=solve(v,p));
        }
    }
    return 0;
}
相關文章
相關標籤/搜索