关于多测清空(kruskal重构树)
查看原帖
关于多测清空(kruskal重构树)
1066579
XP3301_Pipi楼主2024/9/28 07:59

rt,我在重构树上倍增要用的 f 数组,不清空就会 WA ON #11,代码中 f 数组应该是每次都会重新计算,不会用到前面几组数据的答案,有没有 dalao 能够解释一下

#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define pil pair<int,ll>
#define ull unsigned long long
using namespace std;
const int N=2e5+5,M=8e5+5;
const long long LINF=0x3f3f3f3f3f3f3f3fll;
const int IINF=0x3f3f3f3f;

inline void FileIO() {
	freopen(".in","r",stdin);
	freopen(".out","w",stdout);
}

template<typename Type>
inline void read(Type& res) {
	Type x=0,f=1;
	char c=' ';
	while(!isdigit(c)) {
		if(c=='-') f=-1;
		c=getchar();
	}
	while(isdigit(c)){
        x=(x<<3)+(x<<1)+(c^48);
        c=getchar();
    }
	res=x*f;
}

int T,n,m,Q,S,K;
int head[N],tot,cnt,num;
int fa[N<<1],val[N<<1],lg[N<<1],dep[N<<1],f[N<<1][25];
ll dis[N<<1],ans;
bool vis[N];

struct Edge{
    int to,nxt;
    int val,hgt;
}edge[M];

struct Edg2{
    int u,v,w;
    bool operator<(const Edg2& tmp)const{
        return w>tmp.w;
    }
}et[M];

vector<int> e[N<<1];

void Clear(){
    for(int i=1;i<=num;i++) e[i].clear();
    memset(head,0,sizeof(head));
    memset(dis,0x3f,sizeof(dis));
    memset(dep,0,sizeof(dep));
    memset(f,0,sizeof(f));
    tot=cnt=num=ans=0;
}

void Add(int u,int v,int w,int h){
    edge[++tot].to=v;
    edge[tot].nxt=head[u];
    edge[tot].val=w;
    edge[tot].hgt=h;
    head[u]=tot;
}

int GetU(int u){
    return (u+K*ans-1)%n+1;
}

int GetP(int p){
    return (p+K*ans)%(S+1);
}

int Find(int x){
    if(fa[x]==x) return x;
    return fa[x]=Find(fa[x]);
}

void Dijkstra(){
    priority_queue<pli,vector<pli>,greater<pli> > q;
    q.push(make_pair(0,1));
    memset(dis,0x3f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dis[1]=0;
    while(q.size()){
        int x=q.top().second;
        q.pop();
        if(vis[x]) continue;
        vis[x]=1;
        for(int i=head[x];i;i=edge[i].nxt){
            int t=edge[i].to;
            if(dis[t]>dis[x]+edge[i].val){
                dis[t]=dis[x]+edge[i].val;
                q.push(make_pair(dis[t],t));
            }
        }
    }
}

void dfs(int x,int pr){
    dep[x]=dep[pr]+1;
    f[x][0]=pr;
    for(int i=1;i<=lg[dep[x]];i++)
        f[x][i]=f[f[x][i-1]][i-1];
    for(int t:e[x]) dfs(t,x);
}

void Solve(){
    read(n),read(m);
    for(int i=1;i<=m;i++){
        int u,v,w,h;
        read(u),read(v),read(w),read(h);
        Add(u,v,w,h);
        Add(v,u,w,h);
        et[i]={u,v,h};
    }
    Dijkstra();
    sort(et+1,et+m+1); num=n;
    for(int i=1;i<=(n<<1);i++) fa[i]=i;
    for(int i=1;i<=n;i++) val[i]=INT_MAX;
    for(int i=1;i<=m;i++){
        int u=et[i].u,v=et[i].v,w=et[i].w;
        int fu=Find(u),fv=Find(v);
        if(fu==fv) continue;
        val[++num]=min({val[fu],val[fu],w});
        dis[num]=min(dis[fu],dis[fv]);
        fa[fu]=num,fa[fv]=num;
        e[num].push_back(fu);
        e[num].push_back(fv);
    }
    dep[0]=-1;
    dfs(num,0);
    read(Q),read(K),read(S);
    while(Q--){
        int u,p;
        read(u),read(p);
        u=GetU(u);
        p=GetP(p);
        for(int i=lg[dep[u]];i>=0;i--){
            if(val[f[u][i]]>p)
                u=f[u][i];
        }
        // printf("U=%d\n",u);
        ans=dis[u];
        printf("%lld\n",dis[u]);
    }
}

signed main(){
//	不开longlong见祖宗!
//	检查数组大小!
//	禁止在int乘int时不开longlong!
//	注意输出格式!
//	STL数据类型拷贝赋值时间复杂度是 O(N)!
//	读入单个字符要用字符串,防毒瘤数据!
//	(1<<63)爆ll,(1<<31)爆int!
//	比赛结束前5min,检查上述7项,并编译运行!!!!!
//	-std=c++14 -O2 -Wall -Wextra -Wshadow -Wl,--stack=536870912
    read(T);
    for(int i=2;i<=400000;i++) 
        lg[i]=lg[i>>1]+1;
    while(T--){
        Solve();
        Clear();
    }
	return 0;
}
2024/9/28 07:59
加载中...