zoukankan      html  css  js  c++  java
  • 2017icpcBeijing C

    题解: 首先查询的是边的编号在[l,r]的有效边  所以我们可以转化成将边的标号大于等于l的边与边的编号小于等于r的边求交集 则为查询的有效边 发现维护是用并查集维护 加边是Log 删边是on的  所以我们考虑离线以后回滚莫队处理答案即可 注意细节就行

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <set>
    #include <map>
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define link(x) for(edge *j=h[x];j;j=j->next)
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=1e5+10;
    const double eps=1e-8;
    #define ll long long
    using namespace std;
    struct edge{int t,v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
    void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;}
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    typedef struct node{
        int l,r,id;
    }node;
    node st[MAXN];
    int tot;
    ll ans[MAXN];
    bool cmp1(node aa,node bb){
    	if(aa.l==bb.l)return aa.r>bb.r;
        return aa.l>bb.l;
    }
    bool cmp2(node aa,node bb){
        if(aa.r==bb.r)return aa.l<bb.l;
        return aa.r<bb.r;
    }
    node d1[MAXN],d2[MAXN],que[MAXN<<1];
    int f[MAXN],p[MAXN];
    int vis[MAXN],num[MAXN];
    vector<node>vec[MAXN];
    int find1(int x){
        if(x==f[x])return x;
        else return find1(f[x]);
    }
    int main(){
        int _=read();
        while(_--){
            int n,m,q;n=read();m=read();q=read();
            int sz=sqrt(m);memset(ans,0,sizeof(ans));
            inc(i,1,m)p[i]=(i-1)/sz+1,vec[i].clear();
            inc(i,1,n)f[i]=i,num[i]=1;
            int t1,t2;
            inc(i,1,m)t1=read(),t2=read(),d1[i].l=min(t1,t2),d1[i].r=max(t1,t2),d1[i].id=i,d2[i]=d1[i],vis[i]=0;
            inc(i,1,q)que[i].l=read(),que[i].r=read(),que[i].id=i,ans[i]=0;
            sort(d1+1,d1+m+1,cmp1);sort(d2+1,d2+m+1,cmp2);
            inc(i,1,q){
                int l=1;int r=m;int ans1=0;
                while(l<=r){
                    int mid=(l+r)>>1;
                    if(d1[mid].l>=que[i].l)l=mid+1,ans1=mid;
                    else r=mid-1;
                }
                if(ans1)vec[p[ans1]].pb(que[i]);
            }
            inc(i,1,p[m])sort(vec[i].begin(),vec[i].end(),cmp2);
            ll ans2=0;
            inc(i,1,p[m]){
                if(!vec[i].size()){
                    ans2=0;
                    for(int j=(i-1)*sz+1;j<=min(m,i*sz);j++){
                        vis[d1[j].id]++;
                    }
                    continue;
                }
                int L=(i-1)*sz+1;int R=1;
                for(int j=0;j<vec[i].size();j++){
                    while(R<=m&&d2[R].r<=vec[i][j].r){
                        vis[d2[R].id]++;
                        if(vis[d2[R].id]==2){
                            int t1=find1(d2[R].l);int t2=find1(d2[R].r);
                            if(t1!=t2){
                                if(num[t1]>num[t2])swap(t1,t2);
                                f[t1]=t2;
                                ans2+=1ll*num[t1]*num[t2];
                                num[t2]+=num[t1];
                            }
                        }
                        R++;
                    }
                    tot=0;
                    while(L<=m&&d1[L].l>=vec[i][j].l){
                        vis[d1[L].id]++;
                        if(vis[d1[L].id]==2){
                            int t1=find1(d1[L].l);int t2=find1(d1[L].r);
                            if(t1!=t2){
                                if(num[t1]>num[t2])swap(t1,t2);
                                f[t1]=t2;
                                ans2+=1ll*(num[t1])*num[t2];
                                num[t2]+=num[t1];
                                st[++tot]=(node){t1,t2,0};                          
                            }
                        }
                        L++;
                    }
                    ans[vec[i][j].id]=ans2;
                    while(tot){
                        f[st[tot].l]=st[tot].l;
                        num[st[tot].r]-=num[st[tot].l];
                        ans2-=1LL*num[st[tot].l]*num[st[tot].r];
                        tot--;
                    }
                    int tt=(i-1)*sz+1;
                    while(L>=tt){L--;vis[d1[L].id]--;}
                    vis[d1[L].id]++;L++; 
                }
                ans2=0;
                for(int j=1;j<=n;j++)f[j]=j,num[j]=1;
                for(int j=1;j<R;j++)if(vis[d2[j].id]>0)vis[d2[j].id]--;
                for(int j=(i-1)*sz+1;j<=min(m,i*sz);j++){
                    vis[d1[j].id]++;
                }
            }
            for(int i=1;i<=q;i++)printf("%lld
    ",ans[i]);
        }
        return 0;
    }
    

     

    The country contains N cities numbered from 1 to N and M undirected roads connecting pairs of cities. There are some queries. Each query is represented by two numbers: L and R , meaning that all the cities whose number is between L and R(L and R are included) are safe, and other cities are not safe. We define city A can reach city B if and only if they are both safe and there exists a path from A to B that the cities on the path are all safe.

    For each query, you need to figure out the number of pairs of cities that can reach each other under the condition given by the query.

    Input

    First line contains one number T which means the number of test cases.

    For each test case, first line contains three numbers, above mentioned N , M and Q.

    Next M lines, each line contains two integers: X, Y (X != Y) which means there is a road between city X and city Y (1 <= X,Y <= N).

    Next Q lines, each line contains two numbers: L, R which indicates an query(1 <= L,R <= N, L <= R).

    T <= 5, N , M <= 50000, Q <= 100000

    Output

    For each test case, output Q lines, each line contains the answer of the correspondent query.

    Sample Input

    1
    6 6 4
    1 2
    2 3
    2 6
    1 5
    2 4
    4 5
    1 4
    3 6
    2 6
    3 4

    Sample Output

    6
    1
    10
    0
  • 相关阅读:
    el标签 2016-06-05 21:39 477人阅读 评论(15) 收藏
    5月英语总结 2016-05-31 21:31 395人阅读 评论(12) 收藏
    通过在__init__.py中定义__all__变量,来简化from*import*的书写
    python已安装包的查看方法和requirements.text的使用
    virtualenv安装 以及在PyCharm中的使用
    利用Fitnesse测试外部jar包
    说一下个人对自动化测试以及测试的看法
    oracle 导入sql文件乱码
    问题收集
    Gson应用:从json格式简单字符串中获取value
  • 原文地址:https://www.cnblogs.com/wang9897/p/9882457.html
Copyright © 2011-2022 走看看