首先从短至长加边,成环则不加
然后
ANS=(R-L+1)-Cnt
Cnt为区间内边的个数
直接搞即可
复杂度?
$N\alpha(N)+QK^2$
要是用cincout就是$N\sqrt N$
1 #include <cstdio> 2 #include <cassert> 3 #include <algorithm> 4 5 using namespace std; 6 7 const int MAXN=111111; 8 const int MAXK=7; 9 10 int N, K, M, Qcnt; 11 bool Ced[MAXN][MAXK]; 12 bool Used[MAXN][MAXK]; 13 int Cnt1[MAXN], Cnt2[MAXN]; 14 int F[MAXN]; 15 16 int read(){ 17 int x=0, f=1;char ch=getchar(); 18 while(ch<'0' || ch>'9'){if(ch=='-') f=-f;ch=getchar();} 19 while(ch>='0' && ch<='9'){x=x*10+(ch-'0');ch=getchar();} 20 return x*f; 21 } 22 23 int Find(int a){ 24 if(F[F[a]]!=F[a]) F[a]=Find(F[a]); 25 return F[a]; 26 } 27 28 int main(){ 29 30 31 N=read();K=read(); 32 33 M=read(); 34 for(int i=1, a, b;i<=M;++i){ 35 a=read();b=read(); 36 if(a>b) swap(a, b); 37 Ced[a][b-a]=true; 38 } 39 40 for(int i=1;i<=N;++i) F[i]=i; 41 for(int i=1;i<=K;++i){ 42 for(int j=1, fx, fy;j<=N;++j){ 43 if(!Ced[j][i]) continue; 44 fx=Find(j);fy=Find(j+i); 45 if(fx!=fy){ 46 Used[j][i]=true; 47 F[fx]=fy; 48 } 49 } 50 } 51 52 for(int i=1;i<=N;++i) 53 for(int j=1;j<=K;++j){ 54 if(Used[i][j]){ 55 ++Cnt1[i+j]; 56 ++Cnt2[i]; 57 } 58 } 59 60 for(int i=1;i<=N;++i){ 61 Cnt1[i]+=Cnt1[i-1];Cnt2[i]+=Cnt2[i-1]; 62 } 63 64 //for(int i=1;i<=N;++i){ 65 // cout << Cnt1[i] << " " << Cnt2[i] << endl; 66 //} 67 68 int Del=0; 69 Qcnt=read(); 70 for(int a, b;Qcnt--;){ 71 Del=0; 72 a=read();b=read(); 73 for(int i=a-1;i+K>b;--i) 74 for(int k=K;i+k>b;--k) 75 if(Used[i][k]) ++Del; 76 //cout << (b-a+1)-(Cnt1[b]-Cnt2[a-1])-Del << endl; 77 printf("%d\n", (b-a+1)-(Cnt1[b]-Cnt2[a-1])-Del); 78 } 79 80 return 0; 81 } 82 83 /* 84 10 5 85 5 86 8 9 87 3 8 88 2 5 89 1 3 90 4 7 91 3 92 3 3 93 4 8 94 4 8 95 96 1 97 4 98 4 99 100 */