80pts求调
查看原帖
80pts求调
551803
BPG_ning楼主2025/1/10 15:14
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
#define mp make_pair
#define fir first
#define sec second
#define pb push_back
const int N=110,M=1e4+10,NM=1e6+10,inf=1e9+10;
int n,m,q,r[N][M],c[N][M];
LL ans[M*3];
struct gsw{int l,r,id;}Q[M*3];
struct edge{
    int u,v,w;
    edge(int uu=0,int vv=0,int ww=0){
        u=uu,v=vv,w=ww;
    }
};
vector<int> preV[M],sufV[M];
vector<edge> preE[M],sufE[M];
LL preans[M],sufans[M];
bool cmp(edge a,edge b){return a.w<b.w;}
int id(int i,int j){return (i-1)*m+j;}
struct FaC{
    int fa[NM];
    int find(int x){return (fa[x]==x?x:fa[x]=find(fa[x]));}
    int merge(int x,int y){
        x=find(x),y=find(y);
        if(x==y) return 0;
        fa[x]=y;
        return 1;
    }
}F;
namespace IO{
    int lim;
    unsigned int SA, SB, SC;
    int Gen() {
        SA ^= SA << 16;
        SA ^= SA >> 5;
        SA ^= SA << 1;
        unsigned int t = SA;
        SA = SB;
        SB = SC;
        SC ^= t ^ SA;
        return SC % lim + 1;
    }
    void read(){
        cin>>n>>m>>SA>>SB>>SC>>lim;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++) r[i][j]=Gen();
        }
        for(int i=1;i<n;i++){
            for(int j=1;j<=m;j++) c[i][j]=Gen();
        }
        cin>>q;
        for(int i=1;i<=q;i++) cin>>Q[i].l>>Q[i].r,Q[i].id=i;
    }
}
void MST(vector<int> V,vector<edge> &E,LL &ans){
    static vector<edge> tE;
    tE.clear();
    swap(E,tE);
    sort(tE.begin(),tE.end(),cmp);
    for(int p:V) F.fa[p]=p;
    for(edge p:tE){
        if(F.merge(p.u,p.v)){
            ans+=p.w;
            E.pb(p);
        }
    }
}
int vis[NM],s[NM];
vector<pii> G[NM];
vector<edge> H;
void dfs1(int x,int fa){
    if(s[x]) vis[x]=1;
    int cnt=0;
    for(pii p:G[x]) if(p.sec!=fa){
        int y=p.sec;
        dfs1(y,x);
        s[x]|=s[y];
        cnt+=s[y];
    }
    if(cnt>=2) vis[x]=1;
}
pii dfs2(int x,int fa){
    int sn=0,cnt=0,Max=0;
    for(pii p:G[x]) if(p.sec!=fa){
        pii y=dfs2(p.sec,x);
        if(y.sec){
            cnt++;
            sn=y.sec;
            Max=max(y.fir,p.fir);
            if(vis[x]) H.pb(edge(x,y.sec,Max));
        }
    }
    if(vis[x]) return mp(0,x);
    if(cnt>=2) assert(0);
    return mp(Max,sn);
}
void get_Tree(vector<int> &V,vector<edge> &E,vector<int> tV){
    for(int p:V){
        vis[p]=s[p]=0;
        G[p].clear();
    }
    for(edge p:E){
        G[p.u].pb(mp(p.w,p.v));
        G[p.v].pb(mp(p.w,p.u));
    }
    for(int p:tV) s[p]=1;
    int rt=tV[0];
    dfs1(rt,0);
    H.clear();
    dfs2(rt,0);
    tV.clear();
    swap(V,tV);
    for(int p:tV) if(vis[p]) V.pb(p);
    E=H;
}
void init(){
    static vector<int> V;
    for(int j=1;j<m;j++){
        preV[j]=preV[j-1],preE[j]=preE[j-1],preans[j]=preans[j-1];
        for(edge p:preE[j]) preans[j]-=p.w;
        for(int i=1;i<=n;i++){
            int idx=id(i,j);
            preV[j].pb(idx);
            if(j!=1){
                preE[j].pb(edge(idx-1,idx,r[i][j-1]));
            }
            if(i!=n){
                preE[j].pb(edge(idx,idx+m,c[i][j]));
            }
        }
        MST(preV[j],preE[j],preans[j]);
        V.clear();
        for(int i=1;i<=n;i++) V.pb(id(i,1));
        for(int i=1;i<=n;i++) V.pb(id(i,j));
        get_Tree(preV[j],preE[j],V);
    }
    for(int j=m;j>1;j--){
        sufV[j]=sufV[j+1],sufE[j]=sufE[j+1],sufans[j]=sufans[j+1];
        for(edge p:sufE[j]) sufans[j]-=p.w;
        for(int i=1;i<=n;i++){
            int idx=id(i,j);
            sufV[j].pb(idx);
            if(j!=m){
                sufE[j].pb(edge(idx,idx+1,r[i][j]));
            }
            if(i!=n){
                sufE[j].pb(edge(idx,idx+m,c[i][j]));
            }
        }
        MST(sufV[j],sufE[j],sufans[j]);
        V.clear();
        for(int i=1;i<=n;i++) V.pb(id(i,m));
        for(int i=1;i<=n;i++) V.pb(id(i,j));
        get_Tree(sufV[j],sufE[j],V);
    }
}
void work(){
    static vector<int> V;
    static vector<edge> E;
    LL ans;
    for(int c=1;c<=q;c++){
        int L=Q[c].l-1,R=Q[c].r+1;
        ans=preans[L]+sufans[R];
        V.clear(),E.clear();
        for(int p:preV[L]) V.pb(p);
        for(int p:sufV[R]) V.pb(p);
        for(edge p:preE[L]) ans-=p.w,E.pb(p);
        for(edge p:sufE[R]) ans-=p.w,E.pb(p);
        for(int i=1;i<=n;i++){
            E.pb(edge(id(i,m),id(i,1),r[i][m]));
        }
        MST(V,E,ans);
        if(L<1 || R>m) assert(0);
        cout<<ans<<'\n';
    }
}
int main(){
    ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
   freopen("C.in","r",stdin);
   freopen("C.out","w",stdout);
    IO::read();
    init();
    work();
    cerr<<1.0*clock()/CLOCKS_PER_SEC<<'\n';
    return 0;
}

虚树做法,调不出来要疯掉了

2025/1/10 15:14
加载中...