2017-2018 ptz Saratov 补题记录
给定长为 n a , n b , n c na, nb, nc n a , n b , n c a , b , c a, b, c a , b , c a , b , c a, b, c a , b , c ( i , j , k ) (i, j, k) ( i , j , k ) ( i , j , k ) (i, j, k) ( i , j , k ) ∣ a i − b j ∣ ≤ d , ∣ b j − c k ∣ ≤ d , ∣ a i − c k ∣ ≤ d |a_i - b_j| \leq d, |b_j - c_k| \leq d, |a_i - c_k| \leq d ∣ a i  − b j  ∣ ≤ d , ∣ b j  − c k  ∣ ≤ d , ∣ a i  − c k  ∣ ≤ d 1 ≤ n ≤ 5 ⋅ 1 0 5 , − 1 0 9 ≤ a i , b i , c i ≤ 1 0 9 1 \leq n \leq 5 \cdot 10^5, - 10^9 \leq a_i, b_i, c_i \leq 10^9 1 ≤ n ≤ 5 ⋅ 1 0 5 , − 1 0 9 ≤ a i  , b i  , c i  ≤ 1 0 9 
枚举 a i , b j , c k a_i, b_j, c_k a i  , b j  , c k  O ( n ⋅ l o g n ) O(n \cdot logn) O ( n ⋅ l o g n ) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include <bits/stdc++.h>  using  namespace  std;using  ll=long  long ;const  int  INF=0x3f3f3f3f ;const  int  N=5e5 +5 ;int  main ()     ios::sync_with_stdio (0 );     cin.tie (0 );cout.tie (0 );     int  d,na,nb,nc;     while (cin>>d>>na>>nb>>nc){         vector<int > a (na,0 ) ,b (nb,0 ) ,c (nc,0 ) ,app ;         for (auto  &x:a) cin>>x;         for (auto  &x:b) cin>>x;         for (auto  &x:c) cin>>x;         ll ans=0 ;         for (int  i=0 ;i<na;i++){             int  lenb=upper_bound (b.begin (),b.end (),a[i]+d)-lower_bound (b.begin (),b.end (),a[i]);             int  lenc=upper_bound (c.begin (),c.end (),a[i]+d)-lower_bound (c.begin (),c.end (),a[i]);             ans+=1ll *lenb*lenc;         }         for (int  i=0 ;i<nb;i++){             int  lena=upper_bound (a.begin (),a.end (),b[i]+d)-lower_bound (a.begin (),a.end (),b[i]+1 );             int  lenc=upper_bound (c.begin (),c.end (),b[i]+d)-lower_bound (c.begin (),c.end (),b[i]);             ans+=1ll *lena*lenc;         }         for (int  i=0 ;i<nc;i++){             int  lena=upper_bound (a.begin (),a.end (),c[i]+d)-lower_bound (a.begin (),a.end (),c[i]+1 );             int  lenb=upper_bound (b.begin (),b.end (),c[i]+d)-lower_bound (b.begin (),b.end (),c[i]+1 );             ans+=1ll *lena*lenb;         }         cout<<ans<<'\n' ;     }     return  0 ; } 
给定树上若干条路径,求最小的点集使得每条路径都至少被一个点覆盖。1 ≤ n , m ≤ 1 0 5 1 \leq n, m \leq 10^5 1 ≤ n , m ≤ 1 0 5 
若在序列上则是经典区间覆盖问题,放在树上考虑类似的贪心,对所有路径的  l c a lca l c a 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 #include <bits/stdc++.h>  using  namespace  std;using  ll=long  long ;const  int  N=1e5 +5 ;set<int > st[N]; int  main ()     ios::sync_with_stdio (0 );     cin.tie (0 );cout.tie (0 );          int  n;     cin>>n;     vector<vector<int >> e (n,vector <int >(0 ));     for (int  i=1 ,x,y;i<n;i++){         cin>>x>>y;         x--,y--;         e[x].push_back (y);         e[y].push_back (x);     }     int  m;     cin>>m;     vector<int > ans (n,0 ) ,vis (n,0 )  ;     for (int  i=0 ;i<m;i++){         int  u,v,lca;         cin>>u>>v;         u--,v--;         if (u==v){             ans[u]=1 ;             continue ;         }         st[u].insert (i);         st[v].insert (i);     }     function<void (int ,int )> dfs=[&](int  x,int  fa){         int  flag=0 ;         for (auto  v:e[x]){             if (v==fa) continue ;             dfs (v,x);             if (st[v].size ()>st[x].size ()) st[x].swap (st[v]);             for (auto  val:st[v]){                 if (st[x].find (val)!=st[x].end ()) flag=1 ;                 st[x].insert (val);             }         }         if (ans[x]){             st[x].clear ();             return ;         }         if (flag){             ans[x]=1 ;             st[x].clear ();         }     };     dfs (0 ,0 );     int  sum=0 ;     for (int  i=0 ;i<n;i++) sum+=ans[i];          cout<<sum<<'\n' ;     for (int  i=0 ;i<n;i++) if (ans[i]) cout<<i+1 <<' ' ;     return  0 ; } 
给定 n n n t i t_i t i  a i a_i a i  0 0 0 0 0 0 1 ≤ n ≤ 2 ⋅ 1 0 5 , 1 ≤ t i , a i ≤ 1 0 9 , t i < t i + 1 ( 1 ≤ i < n ) 1 \leq n \leq 2 \cdot 10^5, 1 \leq t_i, a_i \leq 10^9, t_i < t_{i+1} (1 \leq i < n) 1 ≤ n ≤ 2 ⋅ 1 0 5 , 1 ≤ t i  , a i  ≤ 1 0 9 , t i  < t i + 1  ( 1 ≤ i < n ) 
记 d p i dp_i d p i  
{ d p i = m i n ( m a x ( d p j , t i ) + 2 ⋅ m a x ( a j + 1 , . . . , a i ) ) ( 0 ≤ j < i ) d p [ 0 ] = 0 \begin{cases}
    dp_i = min(max(dp_j, t_i) + 2 \cdot max(a_{j+1}, ..., a_i))(0 \leq j <i)\\
    dp[0] = 0
\end{cases}
 { d p i  = m i n ( m a x ( d p j  , t i  ) + 2 ⋅ m a x ( a j + 1  , . . . , a i  ) ) ( 0 ≤ j < i ) d p [ 0 ] = 0  
显然可以套两个线段树优化。O ( n ⋅ l o g n ) O(n \cdot logn) O ( n ⋅ l o g n ) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 #include <bits/stdc++.h>  using  namespace  std;using  ll=long  long ;const  ll INF=0x3f3f3f3f3f3f3f3f ;const  int  N=2e5 +5 ;struct  tree {    int  l[N<<2 ];     int  r[N<<2 ];     ll lz[N<<2 ];     ll minn[N<<2 ];     void  pushup (int  x)          minn[x]=min (minn[x<<1 ],minn[x<<1 |1 ]);     }     void  build (int  x,int  L,int  R)          l[x]=L;         r[x]=R;         lz[x]=minn[x]=0 ;         if (L==R) return ;         int  mid=L+R>>1 ;         build (x<<1 ,L,mid);         build (x<<1 |1 ,mid+1 ,R);         return ;     }     void  pushdown (int  x)          if (lz[x]){             ll val=lz[x];             minn[x<<1 ]+=val;             lz[x<<1 ]+=val;             minn[x<<1 |1 ]+=val;             lz[x<<1 |1 ]+=val;             lz[x]=0 ;         }     }     void  add (int  x,int  L,int  R,ll val)          if (l[x]>=L&&r[x]<=R){             minn[x]+=val;             lz[x]+=val;             return ;         }         pushdown (x);         if (r[x<<1 ]>=L) add (x<<1 ,L,R,val);         if (l[x<<1 |1 ]<=R) add (x<<1 |1 ,L,R,val);         pushup (x);         return ;     }     ll search (int  x,int  L,int  R)  {         if (L>R) return  INF;         if (l[x]>=L&&r[x]<=R) return  minn[x];         pushdown (x);         ll res=INF;         if (r[x<<1 ]>=L) res=min (res,search (x<<1 ,L,R));         if (l[x<<1 |1 ]<=R) res=min (res,search (x<<1 |1 ,L,R));         return  res;     } }tr[2 ]; int  main ()     ios::sync_with_stdio (0 );     cin.tie (0 );cout.tie (0 );     int  n;     while (cin>>n){         vector<int > t (n+5 ,0 ) ,a (n+5 ,0 )  ;         for (int  i=1 ;i<=n;i++) cin>>t[i]>>a[i];         tr[0 ].build (1 ,1 ,n);         tr[1 ].build (1 ,1 ,n);         vector<ll> dp (n+5 ,INF)  ;         vector<int > st;         st.push_back (0 );         int  pos=1 ;         dp[0 ]=0 ;         for (int  i=1 ;i<=n;i++){             while (st.back ()&&a[st.back ()]<=a[i]){                 int  p=st.back ();                 st.pop_back ();                 tr[0 ].add (1 ,st.back ()+1 ,p,-2ll *a[p]);                 tr[1 ].add (1 ,st.back ()+1 ,p,-2ll *a[p]);             }             tr[0 ].add (1 ,st.back ()+1 ,i,2ll *a[i]);             tr[1 ].add (1 ,st.back ()+1 ,i,2ll *a[i]);             st.push_back (i);             tr[0 ].add (1 ,i,i,dp[i-1 ]);             while (pos<=i&&dp[pos-1 ]<t[i]) pos++;             if (pos<=i&&dp[pos-1 ]>=t[i]) dp[i]=min (dp[i],tr[0 ].search (1 ,pos,i));             dp[i]=min (dp[i],tr[1 ].search (1 ,1 ,pos-1 )+t[i]);         }         cout<<dp[n]<<"\n" ;     }     return  0 ; } 
挺 nb 的题。
给定长为 n n n a a a k k k g c d gcd g c d 2 ≤ n ≤ 1 0 5 , 0 ≤ k ≤ n 2 , 1 ≤ a i ≤ 1 0 18 2 \leq n \leq 10^5, 0 \leq k \leq \frac{n}{2}, 1 \leq a_i \leq 10^{18} 2 ≤ n ≤ 1 0 5 , 0 ≤ k ≤ 2 n  , 1 ≤ a i  ≤ 1 0 1 8 
考虑从 a a a S S S S S S n − k n \frac{n - k}{n} n n − k  S S S S S S m a x max m a x S S S c n t i cnt_i c n t i  i i i g i = g c d ( S , a i ) g_i = gcd(S, a_i) g i  = g c d ( S , a i  ) c n t g i + + cnt_{g_i}++ c n t g i   + + S S S j j j c n t j cnt_j c n t j  c n t j p r i cnt{\frac{j}{pr_i}} c n t p r i  j  p r i pr_i p r i  S S S i i i S S S S S S n − k n - k n − k m a x max m a x 1 0 18 10^{18} 1 0 1 8 S S S S 1 3 S^\frac{1}{3} S 3 1  16 16 1 6 c n t cnt c n t O ( S 1 3 ⋅ t ) O(S^\frac{1}{3} \cdot t) O ( S 3 1  ⋅ t ) t t t S S S O ( T ⋅ ( m a x ( a i ) 1 3 ⋅ t + n ) ) O(T \cdot (max(a_i)^{\frac{1}{3}} \cdot t + n)) O ( T ⋅ ( m a x ( a i  ) 3 1  ⋅ t + n ) ) T T T S S S t t t S S S 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 #include <bits/stdc++.h>  using  namespace  std;using  ll=long  long ;namespace  PR{    set<long  long > res;     long  long  max_factor;     long  long  gcd (long  long  a,long  long  b)          if (b==0 ) return  a;         return  gcd (b,a%b);     }     long  long  power (long  long  a,long  long  b,long  long  mod)          long  long  res=1 ;         while (b){             if (b&1 ) res=(__int128)res*a%mod;             a=(__int128)a*a%mod;             b>>=1 ;         }         return  res;     }     int  Miller_Rabin (long  long  p)          if (p<2 ) return  0 ;         if (p==2 ) return  1 ;         if (p==3 ) return  1 ;         long  long  d=p-1 ,r=0 ;         while (!(d&1 )) ++r,d>>=1 ;         for (long  long  k=0 ;k<10 ;++k){             long  long  a=rand ()%(p-2 )+2 ;             long  long  x=power (a,d,p);             if (x==1 ||x==p-1 ) continue ;             for (int  i=0 ;i<r-1 ;++i){                 x=(__int128)x*x%p;                 if (x==p-1 ) break ;             }             if (x!=p-1 ) return  0 ;         }         return  1 ;     }     long  long  Pollard_Rho (long  long  x)          long  long  s=0 ,t=0 ;         long  long  c=(long  long )rand ()%(x-1 )+1 ;         int  step=0 ,goal=1 ;         long  long  val=1 ;         for (goal=1 ;;goal*=2 ,s=t,val=1 ){             for (step=1 ;step<=goal;++step){                 t=((__int128)t*t+c)%x;                 val=(__int128)val*abs (t-s)%x;                 if ((step%127 )==0 ){                     long  long  d=gcd (val,x);                     if (d>1 ) return  d;                 }             }             long  long  d=gcd (val,x);             if (d>1 ) return  d;         }     }     void  fac (long  long  x)          if (x<=max_factor||x<2 ) return ;         if (Miller_Rabin (x)){             res.insert (x);             return ;         }         long  long  p=x;         while (p>=x) p=Pollard_Rho (x);         fac (x/p),fac (p);     }     void  get_fac (long  long  x)          srand ((unsigned )time (0 ));         res.clear ();         fac (x);     } } int  main ()     ios::sync_with_stdio (0 );     cin.tie (0 );cout.tie (0 );     int  n,k;     cin>>n>>k;     vector<ll> a (n,0 )  ;     for (auto  &x:a) cin>>x;     auto  solve=[&](ll S){         PR::get_fac (S);         map<ll,int > mp;         for (auto  x:a) mp[__gcd(S,x)]++;         for (auto  g:PR::res){             for (auto  it=mp.rbegin ();it!=mp.rend ();it++){                 auto  [x,cnt]=(*it);                 if (x%g==0 ) mp[x/g]+=cnt;             }         }         ll res=0 ;         for (auto  [val,cnt]:mp) if (cnt>=n-k) res=max (res,val);         return  res;     };     ll ans=1 ;     vector<int > p (n,0 )  ;     iota (p.begin (),p.end (),0 );     srand (time (0 ));     for (int  i=0 ;i<60 ;i++){         random_shuffle (p.begin (),p.end ());         ans=max (ans,solve (a[p[1ll *rand ()*rand ()*rand ()%n]]));     }     cout<<ans;     return  0 ; } 
给定 n n n m m m o a i + d i ≤ o b i + T o_{a_i} + d_i \leq o_{b_i} + T o a i   + d i  ≤ o b i   + T o i o_i o i  T T T 1 ≤ n ≤ 1 0 3 , 0 ≤ m ≤ 2 ⋅ 1 0 3 , − 1 0 5 ≤ o i ≤ 1 0 5 , 1 ≤ a i , b i ≤ n , 1 ≤ d i ≤ 100 1 \leq n \leq 10^3, 0 \leq m \leq 2 \cdot 10^3, - 10^5 \leq o_i \leq 10^5, 1 \leq a_i, b_i \leq n, 1 \leq d_i \leq 100 1 ≤ n ≤ 1 0 3 , 0 ≤ m ≤ 2 ⋅ 1 0 3 , − 1 0 5 ≤ o i  ≤ 1 0 5 , 1 ≤ a i  , b i  ≤ n , 1 ≤ d i  ≤ 1 0 0 o i o_i o i  ? ? ? 
显然对于 T T T d i s b i ≥ d i s a i + d i − T dis_{b_i} \geq dis_{a_i} + d_i - T d i s b i   ≥ d i s a i   + d i  − T o i o_i o i  d i s o i ≤ o i , d i s o i ≥ o i dis_{o_i} \leq o_i, dis_{o_i} \geq o_i d i s o i   ≤ o i  , d i s o i   ≥ o i  O ( l o g ( 1 0 9 ) ⋅ n ) O(log(10^9) \cdot n) O ( l o g ( 1 0 9 ) ⋅ n ) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 #include <bits/stdc++.h>  using  namespace  std;using  ll=long  long ;using  pid=pair<int ,double >;const  double  INF=1e9 ;int  main ()     ios::sync_with_stdio (0 );     cin.tie (0 );cout.tie (0 );     int  n,m;     while (cin>>n>>m){         vector<string> str (n,"" )  ;         vector<int > d (n,0 )  ;         vector<array<int ,3>> edge (m);         for (int  i=0 ;i<n;i++){             cin>>str[i];             if (str[i]=="?" ) d[i]=-INF;             else  d[i]=stoi (str[i]);         }         for (auto  &[u,v,w]:edge){             cin>>u>>v>>w;             u--,v--;         }         vector<double > dis (n+1 ,-INF)  ;         auto  check=[&](double  mid){             vector<int > vis (n+1 ,0 );             vector<vector<pid>> e (n+1 ,vector <pid>(0 ));             for (int  i=0 ;i<n;i++) if (d[i]!=-INF){                 e[n].push_back ({i,d[i]});                 e[i].push_back ({n,-d[i]});             }             for (auto  [u,v,w]:edge) e[u].push_back ({v,w-mid});             for (int  i=0 ;i<n;i++) dis[i]=-INF;             dis[n]=0 ;             queue<int > q;             q.push (n);             for (int  i=0 ;i<n;i++) q.push (i);             while (!q.empty ()){                 int  x=q.front ();                 q.pop ();                 for (auto  [v,w]:e[x]){                     if (dis[v]<dis[x]+w){                         dis[v]=dis[x]+w;                         vis[v]++;                         if (vis[v]>n) return  0 ;                         q.push (v);                     }                 }             }             return  1 ;         };         double  l=0 ,r=1e9 ;         for (int  i=0 ;i<60 ;i++){             double  mid=(l+r)/2 ;             if (check (mid)) r=mid;             else  l=mid;         }         cout<<fixed<<setprecision (9 )<<r<<"\n" ;         check (r);         for (int  i=0 ;i<n;i++) cout<<dis[i]<<" \n" [i+1 ==n];     }     return  0 ; } 
长为 n n n a a a m m m q q q [ l , r ] [l, r] [ l , r ] m m m 1 ≤ n ≤ 2 ⋅ 1 0 5 , 1 ≤ m ≤ 20 , 0 ≤ a i ≤ 1 0 9 , 1 ≤ q ≤ 2 ⋅ 1 0 5 1 \leq n \leq 2 \cdot 10^5, 1 \leq m \leq 20, 0 \leq a_i \leq 10^9, 1 \leq q \leq 2 \cdot 10^5 1 ≤ n ≤ 2 ⋅ 1 0 5 , 1 ≤ m ≤ 2 0 , 0 ≤ a i  ≤ 1 0 9 , 1 ≤ q ≤ 2 ⋅ 1 0 5 
显然可以有线段树合并区间背包的方法,但复杂度为 O ( n ⋅ m 2 ⋅ l o g n ) O(n \cdot m^2 \cdot logn) O ( n ⋅ m 2 ⋅ l o g n ) 除非像 Pedestrian1  一样卡常。 [ l i , r i ] [l_i, r_i] [ l i  , r i  ] [ L , R ] [L, R] [ L , R ] m i d = ( L + R ) / 2 mid = (L + R) / 2 m i d = ( L + R ) / 2 r i ≤ m i d r_i \leq mid r i  ≤ m i d l i ≥ m i d + 1 l_i \geq mid+1 l i  ≥ m i d + 1 O ( n ) O(n) O ( n ) d p l i , j , d p r i , j dpl_{i,j}, dpr_{i,j} d p l i , j  , d p r i , j  [ i , m i d ] [i, mid] [ i , m i d ] [ m i d + 1 , i ] [mid+1, i] [ m i d + 1 , i ] m m m j j j O ( m ) O(m) O ( m ) O ( n ⋅ m ⋅ l o g n + m ⋅ q ) O(n \cdot m \cdot logn + m \cdot q) O ( n ⋅ m ⋅ l o g n + m ⋅ q ) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 #include <bits/stdc++.h>  using  namespace  std;using  ll=long  long ;const  int  mod=1e9 +7 ;const  int  N=2e5 +5 ;int  main ()     ios::sync_with_stdio (0 );     cin.tie (0 );cout.tie (0 );     int  n,m;     cin>>n>>m;     vector<int > a (n+5 ,0 )  ;     for (int  i=1 ;i<=n;i++) cin>>a[i];     int  q;     cin>>q;     vector<int > ql (q+5 ,0 ) ,qr (q+5 ,0 )  ;     for (int  i=1 ;i<=q;i++) cin>>ql[i]>>qr[i];     vector<array<int ,20>> dp (n+5 );     vector<int > qry,ans (q+5 ,0 );     for (int  i=1 ;i<=q;i++) qry.push_back (i);     function<void (int ,int ,vector<int >&)> calc=[&](int  l,int  r,vector<int > &qry){         if (qry.empty ()) return ;         if (l==r){             if (a[l]%m==0 ) for (auto  x:qry) ans[x]=(ans[x]+1 )%mod;             return ;         }         int  mid=l+r>>1 ;         vector<int > qry1,qry2,qry3;         for (auto  x:qry){             if (qr[x]<=mid) qry1. push_back (x);             else  if (ql[x]>=mid+1 ) qry2. push_back (x);             else  qry3. push_back (x);         }         calc (l,mid,qry1);         calc (mid+1 ,r,qry2);         for (int  i=l;i<=r;i++)             for (int  j=0 ;j<m;j++) dp[i][j]=0 ;         for (int  i=mid;i>=l;i--){             dp[i][a[i]%m]=(dp[i][a[i]%m]+1 )%mod;             if (i+1 <=mid){                 for (int  j=0 ;j<m;j++)                     dp[i][(j+a[i]%m)%m]=(dp[i][(j+a[i]%m)%m]+dp[i+1 ][j])%mod;                 for (int  j=0 ;j<m;j++)                     dp[i][j]=(dp[i][j]+dp[i+1 ][j])%mod;             }         }         for (int  i=mid+1 ;i<=r;i++){             dp[i][a[i]%m]=(dp[i][a[i]%m]+1 )%mod;             if (i-1 >=mid+1 ){                 for (int  j=0 ;j<m;j++)                     dp[i][(j+a[i]%m)%m]=(dp[i][(j+a[i]%m)%m]+dp[i-1 ][j])%mod;                 for (int  j=0 ;j<m;j++)                     dp[i][j]=(dp[i][j]+dp[i-1 ][j])%mod;             }         }         for (auto  x:qry3){             for (int  i=0 ;i<m;i++) ans[x]=(ans[x]+1ll *dp[ql[x]][i]*dp[qr[x]][(m-i)%m]%mod)%mod;             ans[x]=(ans[x]+dp[ql[x]][0 ])%mod;             ans[x]=(ans[x]+dp[qr[x]][0 ])%mod;         }         return ;     };     calc (1 ,n,qry);     for (int  i=1 ;i<=q;i++) cout<<(ans[i]+1 )%mod<<'\n' ;     return  0 ; } 
给定长为 n n n s s s q q q t t t s s s t t t 1 ≤ n , q ≤ 1 0 5 , ∑ ∣ t ∣ ≤ 1 0 5 1 \leq n, q \leq 10^5, \sum|t| \leq 10^5 1 ≤ n , q ≤ 1 0 5 , ∑ ∣ t ∣ ≤ 1 0 5 
考虑根号分治,对于长度大于等于 n \sqrt{n} n  t t t k m p kmp k m p n \sqrt{n} n  t t t A C AC A C A C AC A C d p i , 0 / 1 dp_{i,0/1} d p i , 0 / 1  A C AC A C f a i l fail f a i l d p dp d p O ( n ⋅ n ) O(n \cdot \sqrt{n}) O ( n ⋅ n  ) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 #include <bits/stdc++.h>  using  namespace  std;const  int  N=1e5 +5 ;const  int  M=26 ;struct  Trie {    int  tot;     int  nex[N][M];     int  fail[N];     int  len[N];     int  pos[N];     int  ans[N][2 ];     void  clear ()          tot=0 ;         fail[0 ]=len[0 ]=ans[0 ][0 ]=0 ;         ans[0 ][1 ]=-1 ;         memset (nex[0 ],0 ,sizeof (nex[0 ]));     }     Trie (){         clear ();     }     int  addnode ()          tot++;         fail[tot]=len[tot]=ans[tot][0 ]=0 ;         ans[tot][1 ]=-1 ;         memset (nex[tot],0 ,sizeof (nex[tot]));         return  tot;     }     void  insert (string s,int  ind)          int  u=0 ;         for (int  i=0 ;i<s.size ();i++){             int  w=s[i]-'a' ;             if (!nex[u][w]) nex[u][w]=addnode ();             len[nex[u][w]]=len[u]+1 ;             u=nex[u][w];         }         pos[ind]=u;     }     void  buildfail ()          queue<int > q;         for (int  i=0 ;i<M;i++) if (nex[0 ][i]) q.push (nex[0 ][i]);         while (!q.empty ()){             int  u=q.front ();             q.pop ();             for (int  i=0 ;i<M;i++){                 if (nex[u][i]){                     int  v=nex[u][i];                     fail[v]=nex[fail[u]][i];                     q.push (nex[u][i]);                 }                 else  nex[u][i]=nex[fail[u]][i];             }         }     } }acam; int  main ()     ios::sync_with_stdio (0 );     cin.tie (0 );cout.tie (0 );     int  n,q;     cin>>n>>q;     int  blo=sqrt (n);     string s;     cin>>s;     vector<string> t (q,"" )  ;     vector<int > ans (q,0 ) ,fail (n,0 )  ;     for (int  i=0 ;i<q;i++){         cin>>t[i];         if (t[i].size ()<=blo) acam.insert (t[i],i);         else  if (t[i].size ()<=n){             fail[0 ]=-1 ;             for (int  j=1 ;j<t[i].size ();j++){                 for (int  k=fail[j-1 ];;k=fail[k]){                     if (t[i][k+1 ]==t[i][j]){                         fail[j]=k+1 ;                         break ;                     }                     else  if (k==-1 ){                         fail[j]=-1 ;                         break ;                     }                 }             }             int  now=-1 ;             for (int  j=0 ;j<n;j++){                 while (now!=-1 &&t[i][now+1 ]!=s[j]) now=fail[now];                 if (t[i][now+1 ]==s[j]) now++;                 if (now+1 ==t[i].size ()){                     ans[i]++;                     now=-1 ;                 }             }         }     }     acam.buildfail ();     int  now=0 ;     for (int  i=0 ;i<n;i++){         now=acam.nex[now][s[i]-'a' ];         for (int  p=now;p;p=acam.fail[p]){             if (acam.ans[p][1 ]+acam.len[p]<=i){                 acam.ans[p][0 ]++;                 acam.ans[p][1 ]=i;             }         }     }     for (int  i=0 ;i<q;i++){         if (t[i].size ()<=blo) cout<<acam.ans[acam.pos[i]][0 ]<<"\n" ;         else  cout<<ans[i]<<"\n" ;     }     return  0 ; } 
给定 n n n m m m 1 1 1 2 ≤ n ≤ 2 ⋅ 1 0 5 , n − 1 ≤ m ≤ 2 ⋅ 1 0 5 , 1 ≤ w i ≤ 1 0 9 2 \leq n \leq 2 \cdot 10^5, n - 1 \leq m \leq 2 \cdot 10^5, 1 \leq w_i \leq 10^9 2 ≤ n ≤ 2 ⋅ 1 0 5 , n − 1 ≤ m ≤ 2 ⋅ 1 0 5 , 1 ≤ w i  ≤ 1 0 9 w i w_i w i  
首先从 1 1 1 d i s v i = d i s u i + w i dis_{v_i} = dis_{u_i} + w_i d i s v i   = d i s u i   + w i  0 0 0 D A G DAG D A G 1 1 1 0 0 0 
边指向的点入度为 1 1 1  
边指向的点入度不为 1 1 1 0 0 0  
 
问题即转换为对于每个点 x x x 
初始将 x x x  
若一个点的所有指向它的节点都被染色,则它也被染色 
 
例如,下图每个节点的答案为: 6 , 5 , 1 , 2 , 1 , 1 6, 5, 1, 2, 1, 1 6 , 5 , 1 , 2 , 1 , 1 
 
令 S ( x ) S(x) S ( x ) x x x S ( x ) , S ( y ) S(x), S(y) S ( x ) , S ( y ) 1 1 1 0 0 0 
1 1 1 若 x x x 1 1 1 x x x  
若 x x x 1 1 1 x x x l c a lca l c a  
 
具体构造时从 1 1 1 x x x l c a lca l c a O ( n ⋅ l o g n ) O(n \cdot logn) O ( n ⋅ l o g n ) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 #include <bits/stdc++.h>  using  namespace  std;using  ll=long  long ;using  pii=pair<int ,int >;using  pll=pair<ll,ll>;const  ll INF=0x3f3f3f3f3f3f3f3f ;int  main ()     ios::sync_with_stdio (0 );     cin.tie (0 );cout.tie (0 );     int  n,m;     cin>>n>>m;     vector<array<int ,3>> edge (m);     vector<vector<pii>> e (n,vector <pii>(0 ));     for (auto  &[u,v,w]:edge){         cin>>u>>v>>w;         u--,v--;         e[u].push_back ({v,w});         e[v].push_back ({u,w});     }     vector<ll> dis (n,INF)  ;     auto  dij=[&](){         priority_queue<pll,vector<pll>,greater<pll>> q;         dis[0 ]=0 ;         q.push ({dis[0 ],0 });         while (!q.empty ()){             auto  [d,x]=q.top ();             q.pop ();             if (d>dis[x]) continue ;             for (auto  [v,w]:e[x]){                 if (dis[v]>dis[x]+w){                     dis[v]=dis[x]+w;                     q.push ({dis[v],v});                 }             }         }     };     dij ();     vector<int > in (n,0 ) ,sz (n,1 ) ,dep (n,0 )  ;     vector<array<int ,18>> f (n);     vector<vector<int >> ed (n,vector <int >(0 )),fa (n,vector <int >(0 ));     for (int  i=0 ;i<n;i++) e[i].clear ();     for (auto  [u,v,w]:edge){         if (dis[v]==dis[u]+w){             fa[v].push_back (u);             e[u].push_back ({v,1 });             in[v]++;         }         else  if (dis[u]==dis[v]+w){             fa[u].push_back (v);             e[v].push_back ({u,1 });             in[u]++;         }     }     auto  get_lca=[&](int  x,int  y){         if (x==y) return  x;         if (dep[x]<dep[y]) swap (x,y);         for (int  i=17 ;i>=0 ;i--) if (dep[f[x][i]]>=dep[y]) x=f[x][i];         for (int  i=17 ;i>=0 ;i--) if (f[x][i]!=f[y][i]){             x=f[x][i];             y=f[y][i];         }         while (x!=y){             x=f[x][0 ];             y=f[y][0 ];         }         return  x;     };     queue<int > q;     for (int  i=0 ;i<n;i++) if (!in[i]) q.push (i);     while (!q.empty ()){         int  x=q.front ();         q.pop ();         for (auto  [v,w]:e[x]){             in[v]--;             if (!in[v]){                 if (fa[v].size ()==1 ){                     dep[v]=dep[x]+1 ;                     ed[x].push_back (v);                     f[v][0 ]=x;                     for (int  i=1 ;i<18 ;i++) f[v][i]=f[f[v][i-1 ]][i-1 ];                 }                 else {                     int  lca=fa[v].back ();                     fa[v].pop_back ();                     while (fa[v].size ()){                         lca=get_lca (lca,fa[v].back ());                         fa[v].pop_back ();                     }                     dep[v]=dep[lca]+1 ;                     ed[lca].push_back (v);                     f[v][0 ]=lca;                     for (int  i=1 ;i<18 ;i++) f[v][i]=f[f[v][i-1 ]][i-1 ];                 }                 q.push (v);             }         }     }     function<void (int )> dfs=[&](int  x){         for (auto  v:ed[x]){             dfs (v);             sz[x]+=sz[v];         }     };     dfs (0 );     for (auto  [u,v,w]:edge){         if (dis[v]==dis[u]+w) in[v]++;         else  if (dis[u]==dis[v]+w) in[u]++;     }     for (auto  [u,v,w]:edge){         if (dis[v]==dis[u]+w){             if (in[v]==1 ) cout<<sz[v]<<"\n" ;             else  cout<<"0\n" ;         }         else  if (dis[u]==dis[v]+w){             if (in[u]==1 ) cout<<sz[u]<<"\n" ;             else  cout<<"0\n" ;         }         else  cout<<"0\n" ;     }     return  0 ; }