1010 图之图

\(因为题解感觉已经很周到了仅为不懂根号分治复杂度的做一个补充\)
\(就是反向插入边时这样的点最多有m/lim个 那么平均到每个位置所贡献的压力也为m/lim\)

#include<bits/stdc++.h>
#define int long long
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define pb push_back
#define pii pair<int,int>
using namespace std;
const int mod=1e9+7;
int gcd(int a,int b){return b?gcd(b,a%b):a;};
int qpw(int a,int b){int ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
int inv(int x){return qpw(x,mod-2);}
constexpr int N=1e5+10;
vector<int>G[N];
vector<int>H[N];
int dat[N],sum[N];
vector<int>vis(N,0);
void solve() {
    int n,c;cin>>n>>c;
    memset(dat,0,sizeof(dat));
    memset(sum,0,sizeof(sum));
    vector<int>a(n+1);
    for (int i=1;i<=n;i++)cin>>a[i];
    for (int i=1;i<=max(n,c);i++)G[i].clear(),H[i].clear(),vis[i]=0;
    int m;cin>>m;
    for (int i=1;i<=m;i++) {
        int u,v;cin>>u>>v;
        G[u].pb(v);
        if (u!=v)G[v].pb(u);
    }
    int lim=sqrt(n);
    for (int i=1;i<=c;i++) {
        if (G[i].size()>lim) {
            for (auto son:G[i])H[son].pb(i);//这样的点最多有m/lim个 那么平均到每个位置所贡献的压力也为m/lim
            vis[i]=1;
        }
    }
    for (int i=1;i<=n;i++) {
        int x=a[i];
        int cur=(i==1);
        if (vis[x]) {
            cur=(cur+dat[x])%mod;
        }else {
            for (int son:G[x]) {
                cur=(cur+sum[son])%mod;
            }
        }
        if (i==n) {
            cout<<cur<<'\n';
            return;
        }
        sum[x]=(sum[x]+cur)%mod;
        for (auto &son:H[x]) {
            dat[son]=(dat[son]+cur)%mod;
        }
    }
}
signed main(){
    // init();
    ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    int _=1;
    cin>>_;
    while(_--)solve();
}
posted @ 2025-03-30 18:36  archer2333  阅读(60)  评论(0)    收藏  举报