cf453div2E

很有趣的一道题 只有奇圈意味着只有单圈 然后dfs求出单圈 p[x]=y表示[x,y]ok 然后二分求解

  1 #include<cstdio> 
  2 #include<cstring>
  3 #include<cmath>
  4 #include<ctime>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<queue>
  8 #include<stack>
  9 #include<set>
 10 #define esp (1e-6)
 11 #define inf (0x3f3f3f3f)
 12 #define l(a) ((a)<<1)
 13 #define r(a) ((a)<<1|1)
 14 #define b(a) (1<<(a))
 15 #define rep(i,a,b) for(int i=a;i<=(b);i++)
 16 #define clr(a) memset(a,0,sizeof(a))
 17 typedef long long ll;
 18 typedef unsigned long long ull;
 19 using namespace std;
 20 int readint(){
 21     int t=0,f=1;char c=getchar();
 22     while(!isdigit(c)){
 23         if(c=='-') f=-1;
 24         c=getchar();
 25     }
 26     while(isdigit(c)){
 27         t=(t<<3)+(t<<1)+c-'0';
 28         c=getchar();
 29     }
 30     return t*f;
 31 }
 32 const int maxn=300009,maxm=600009;
 33 struct edge{
 34     int v;
 35     edge*next;
 36 }e[maxm],*pt=e,*fir[maxn];
 37 int n,m,circnt,a[maxn],d[maxn],p[maxn];
 38 ll s[maxn],sum[maxn];
 39 bool check[maxn];
 40 void mul(){
 41     rep(i,1,n+1) s[i]=ll(i)*ll(i-1)/2ll;
 42 }
 43 void add(int u,int v){
 44     pt->v=v;pt->next=fir[u];
 45     fir[u]=pt++;
 46 }
 47 void addedge(int u,int v){
 48     add(u,v);add(v,u);
 49 }
 50 stack<int>S;
 51 void Dfs(int x,int f){
 52     S.push(x);check[x]=1;
 53     for(edge*e=fir[x];e;e=e->next) if(e->v!=f&&!p[e->v]){
 54         if(check[e->v]){
 55             int t=-1,cnt=0,mx=0,mn=maxn;++circnt;
 56             while(t!=e->v){
 57                 t=S.top();S.pop();
 58                 p[t]=circnt;a[++cnt]=t;
 59                 mn=min(t,mn);
 60                 mx=max(t,mx);
 61             }
 62             for(int i=cnt;i;i--) S.push(a[i]);
 63             d[mn]=mx;
 64         }else Dfs(e->v,x);    
 65     }
 66     S.pop();
 67 }
 68 void cal(){
 69     rep(i,1,n+1) d[i]=n+1;
 70     rep(i,1,n) if(!check[i]) Dfs(i,-1);
 71     for(int i=n;i;i--) d[i]=min(d[i],d[i+1]);
 72     rep(i,1,n) d[i]--;
 73     for(int i=n;i;i--) sum[i]=sum[i+1]+ll(d[i]);
 74     //puts("");rep(i,1,n) printf("%d ",d[i]);puts("");
 75 }
 76 int main(){
 77     //freopen("#input.txt","r",stdin);
 78     //freopen("#output.txt","w",stdout);
 79     n=readint();m=readint();
 80     mul();
 81     rep(i,1,m){
 82         int U=readint(),V=readint();
 83         addedge(U,V);
 84     }
 85     cal();
 86     int q=readint();
 87     while(q--){
 88         int l=readint(),r=readint(),L=l,R=r;
 89         while(L<R){
 90             int mid=(L+R)>>1;
 91             if(d[mid]<r) L=mid+1;
 92             else R=mid;     
 93         }
 94         ll ans=s[r-l+1]+ll(r-l+1)-ll(r)*ll(L-l)+sum[l]-sum[L];
 95         cout<<ans<<endl;
 96     } 
 97     //fclose(stdin);
 98     //fclose(stdout);
 99     return 0;
100 }
View Code

 

posted @ 2017-12-22 15:03  ChenThree  阅读(100)  评论(0编辑  收藏  举报