基础算法
二分
int bisearch ( int l, int r, int x)
{
while ( l < r)
{
int mid = l + r >> 1 ;
if ( check ( mid) ) r = mid;
else l = mid + 1 ;
}
return l;
}
高精度
# include <iostream>
# include <vector>
# include <cstdio>
using namespace std;
vector< int > add ( vector< int > & A, vector< int > & B)
{
vector< int > C;
int t = 0 ;
for ( int i = 0 ; i < A. size ( ) || i < B. size ( ) ; i++ )
{
if ( i < A. size ( ) )
t += A[ i] ;
if ( i < B. size ( ) )
t += B[ i] ;
C. push_back ( t % 10 ) ;
t /= 10 ;
}
if ( t)
C. push_back ( 1 ) ;
return C;
}
int main ( )
{
string a, b;
int t;
cin >> t;
for ( int o = 1 ; o <= t; o++ )
{
vector< int > A, B;
cin >> a >> b;
for ( int i = a. size ( ) - 1 ; i >= 0 ; i-- )
A. push_back ( a[ i] - '0' ) ;
for ( int i = b. size ( ) - 1 ; i >= 0 ; i-- )
B. push_back ( b[ i] - '0' ) ;
auto C = add ( A, B) ;
cout<< "Case " << o<< ":" << endl;
cout<< a<< " + " << b<< " = " ;
for ( int i = C. size ( ) - 1 ; i >= 0 ; i-- )
printf ( "%d" , C[ i] ) ;
cout<< endl;
if ( o!= t)
cout<< endl;
}
}
java大数
import java. util. Scanner ;
import java. math. * ;
public class Main
{
public static void main ( String [ ] args)
{
Scanner cin = new Scanner ( System . in) ;
int t, i= 1 ;
t= cin. nextInt ( ) ;
while ( i<= t)
{
i++ ;
BigInteger n, n1, k, bottom;
n= cin. nextBigInteger ( ) ;
BigInteger s1= new BigInteger ( "1" ) ;
BigInteger s2= new BigInteger ( "2" ) ;
BigInteger mods= new BigInteger ( "1000000007" ) ;
n1= n. add ( s1) ;
BigInteger sss;
BigInteger s12= new BigInteger ( "12" ) ;
BigInteger nd2;
nd2= n1. pow ( 2 ) ;
BigInteger nd21;
nd21= nd2. subtract ( s1) ;
k= nd2. multiply ( nd21) ;
k= k. divide ( s12) ;
bottom= n. multiply ( n1) ;
BigInteger bottom1, n2n1;
bottom1= n. multiply ( n1) ;
n2n1= n. multiply ( s2) ;
n2n1= n2n1. add ( s1) ;
bottom1= bottom1. multiply ( n2n1) ;
bottom= bottom. multiply ( bottom1) ;
bottom= bottom. divide ( s12) ;
BigInteger ans;
ans= bottom;
BigInteger s;
s= n. multiply ( n1) ;
s= s. divide ( s2) ;
s= s. subtract ( s1) ;
BigInteger ans2, ks;
ks= k. multiply ( s) ;
ans= ans. add ( ks) ;
System . out. println ( ans. mod ( mods) ) ;
ans2= n. pow ( 2 ) ;
ans2= ans2. multiply ( bottom) ;
System . out. println ( ans2. mod ( mods) ) ;
}
}
}
归并排序
void merge_sort ( int start, int end) {
if ( start>= end) {
return ;
}
int start1= start, end1= ( start+ end) / 2 , start2= end1+ 1 , end2= end;
merge_sort ( start1, end1) ;
merge_sort ( start2, end2) ;
int k= start;
while ( start1<= end1&& start2<= end2) {
arr[ k++ ] = a[ start1] < a[ start2] ? a[ start1++ ] : a[ start2++ ] ;
}
while ( start1<= end1) {
arr[ k++ ] = a[ start1++ ] ;
}
while ( start2<= end2) {
arr[ k++ ] = a[ start2++ ] ;
}
for ( int i= start; i<= end; i++ ) {
a[ i] = arr[ i] ;
}
}
第k小数
# include <bits/stdc++.h>
using namespace std;
# define ll long long
const int maxn = 5e6 + 10 ;
inline int read ( )
{
int x = 0 , f = 1 ;
char ch = getchar ( ) ;
while ( ch < '0' || ch > '9' )
{
if ( ch == '-' )
f = - 1 ;
ch = getchar ( ) ;
}
while ( ch >= '0' && ch <= '9' )
{
x = ( x << 1 ) + ( x << 3 ) + ( ch ^ 48 ) ;
ch = getchar ( ) ;
}
return x * f;
}
int q[ maxn] ;
int quick_sort ( int q[ ] , int l, int r, int k)
{
if ( l >= r)
return q[ l] ;
int i = l - 1 , j = r + 1 , x = q[ l + r >> 1 ] ;
while ( i < j)
{
do
i++ ;
while ( q[ i] < x) ;
do
j-- ;
while ( q[ j] > x) ;
if ( i < j)
swap ( q[ i] , q[ j] ) ;
}
if ( j - l + 1 >= k)
return quick_sort ( q, l, j, k) ;
else
return quick_sort ( q, j + 1 , r, k - ( j - l + 1 ) ) ;
}
int main ( )
{
int n, k;
int t;
cin >> t;
while ( t-- )
{
n= read ( ) ;
k= read ( ) ;
for ( int i = 0 ; i < n; i++ )
q[ i] = read ( ) ;
cout << quick_sort ( q, 0 , n - 1 , k) << endl;
}
}
三分
int three_fen ( int l, int r)
{
while ( l< r) {
int m1= ( 2 * l+ r) / 3 ;
int m2= ( 2 * r+ l+ 2 ) / 3 ;
if ( calc ( m1) <= calc ( m2) )
r= m2- 1 ;
else {
l= m1+ 1 ;
}
}
return l;
}
数组模拟双向链表
# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N= 10000015 , mod= 1e9 + 7 ;
template < typename T >
void Debug ( T x, string s) {
cout<< s<< ": " << x<< endl;
}
struct node
{
int val, p_cnt;
int next, last;
} a[ N] ;
# define PII pair< int , int >
# define PB push_back
int vis[ N] , vis_p[ N] ;
struct linklist
{
int head= 1 , tail= 1 , sz= 0 , mid= tail;
void insertl ( int tot) { sz++ ;
if ( sz== 1 ) {
head= tail= tot; vis_p[ tot] = 0 ;
a[ tot] . last= - 1 ; a[ tot] . next= - 1 ;
mid= tail;
}
else {
a[ tot] . next= head;
a[ tot] . last= - 1 ;
a[ head] . last= tot;
vis_p[ tot] = vis_p[ head] - 1 ;
head= tot;
if ( sz% 2 == 1 ) {
movel ( ) ;
}
else {
mid= mid;
}
}
}
void insertr ( int tot) {
sz++ ;
if ( sz== 1 ) {
head= tail= tot; vis_p[ tot] = 0 ;
a[ tot] . last= - 1 ; a[ tot] . next= - 1 ;
mid= tot;
}
else {
a[ tot] . last= tail;
a[ tot] . next= - 1 ;
a[ tail] . next= tot;
vis_p[ tot] = vis_p[ tail] + 1 ;
tail= tot;
if ( sz% 2 == 0 ) {
mover ( ) ;
}
else mid= mid;
}
}
void del ( int tot) {
int tl= a[ tot] . last, tr= a[ tot] . next;
if ( tr!= - 1 )
a[ tl] . next= tr;
if ( tl!= - 1 )
a[ tr] . last= tl;
if ( tot== head) {
head= a[ head] . next;
}
if ( tot== tail) {
tail= a[ tail] . last;
}
if ( vis_p[ mid] > vis_p[ tot] ) {
if ( sz% 2 == 1 ) mover ( ) ;
else mid= mid;
}
else if ( vis_p[ mid] < vis_p[ tot] ) {
if ( sz% 2 == 0 ) movel ( ) ;
else mid= mid;
}
else if ( mid== tot) {
if ( sz% 2 == 0 ) movel ( ) ;
else mover ( ) ;
}
sz-- ;
a[ tot] . last= a[ tot] . next= - 1 ;
}
void movel ( ) {
mid= a[ mid] . last;
}
void mover ( ) {
mid= a[ mid] . next;
}
} List;
int tot= 0 ;
void solve ( )
{
int posl= 0 , posr= 0 ; a[ 0 ] . last= a[ 0 ] . next= - 1 ;
int q; scanf ( "%d " , & q) ; char c;
for ( int i= 1 ; i<= q; i++ ) {
scanf ( "%c " , & c) ;
if ( c== 'L' ) { ++ tot;
List. insertl ( tot) ;
}
else if ( c== 'R' ) { ++ tot;
List. insertr ( tot) ;
}
else if ( c== 'G' ) {
int x; scanf ( "%d " , & x) ;
List. del ( x) ;
}
else {
printf ( "%d\n" , List. mid) ;
}
}
}
int main ( )
{
# ifndef ONLINE_JUDGE
freopen ( "b.txt" , "r" , stdin ) ;
freopen ( "bout.txt" , "w" , stdout ) ;
# endif
int t;
t= 1 ;
while ( t-- )
solve ( ) ;
}
快读
template < typename _Tp >
inline _Tp read ( _Tp & x) {
char ch = getchar ( ) , sgn = 0 ; x = 0 ;
while ( ch ^ '-' && ! isdigit ( ch) ) ch = getchar ( ) ;
if ( ch == '-' ) ch = getchar ( ) , sgn = 1 ;
while ( isdigit ( ch) ) x = x * 10 + ch - '0' , ch = getchar ( ) ;
if ( sgn) x = - x;
return x;
}
int main ( ) {
b = read ( a) ;
}
计算程序运行时间
cerr << "Time execute: " << clock ( ) / ( double ) CLOCKS_PER_SEC << " sec" << endl;
STL离散化
sort ( v. begin ( ) , v. end ( ) ) ;
v. erase ( unique ( v. begin ( ) , v. end ( ) ) , v. end ( ) ) ;
数学
gcd
int gcd ( int a, int b)
{
return b? gcd ( b, a% b) : a;
}
扩展欧几里得
# include <iostream>
# include <cstdio>
# include <cmath>
using namespace std;
int exgcd ( int a, int b, int & x, int & y)
{
if ( b== 0 )
{
x= 1 ; y= 0 ;
return a;
}
int r= exgcd ( b, a% b, x, y) ;
int temp= y;
y= x- ( a/ b) * y;
x= temp;
return r;
}
容斥原理
# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int Maxn = 20 ;
int Number[ Maxn + 5 ] ;
ll N, M, Tot;
ll Ans = 0 ;
bool is_prime ( int x)
{
for ( int i= 2 ; i* i<= x; i++ ) {
if ( x% i== 0 ) return false ;
}
return true ;
}
ll Gcd ( ll A, ll B) {
return ! B ? A : Gcd ( B, A % B) ;
}
void Dfs ( ll Cur, ll Cnt, ll Limit, ll LCM) {
if ( Cnt == Limit) {
if ( Limit & 1 ) {
Ans += ( N - 1 ) / LCM;
}
else {
Ans -= ( N - 1 ) / LCM;
}
return ;
}
if ( Cur >= Tot) {
return ;
}
ll NowLCM = LCM == - 1 ? Number[ Cur] : LCM;
Dfs ( Cur + 1 , Cnt + 1 , Limit, Number[ Cur] / Gcd ( NowLCM, Number[ Cur] ) * NowLCM) ;
Dfs ( Cur + 1 , Cnt, Limit, LCM) ;
}
int main ( )
{
# ifndef ONLINE_JUDGE
freopen ( "a.txt" , "r" , stdin ) ;
freopen ( "aout.txt" , "w" , stdout ) ;
# endif
int tot= 0 ;
for ( int i= 2 ; i<= 100 ; i++ ) {
if ( is_prime ( i) ) {
Number[ ++ tot] = i;
}
if ( tot> 17 ) break ;
}
int t; cin>> t;
while ( t-- ) {
cin>> N>> M;
Tot = 1 ;
Ans = 0 ;
Tot= M+ 1 ;
for ( int i = 1 ; i < Tot; i++ ) {
Dfs ( 1 , 0 , i, - 1 ) ;
}
printf ( "%lld\n" , N- Ans- 1 ) ;
}
}
卡特兰数
# include <cstdio>
# include <cstring>
# define N 60
using namespace std;
int main ( )
{
int h[ 101 ] [ 2 * N+ 1 ] , i, j, k, l, n;
memset ( h, 0 , sizeof ( h) ) ;
h[ 0 ] [ 1 ] = 1 ; h[ 1 ] [ 1 ] = 1 ;
for ( i= 2 ; i<= 100 ; i++ )
{
for ( j= 0 ; j< i; j++ )
for ( k= 1 ; k< N; k++ )
for ( l= 1 ; l< N; l++ )
h[ i] [ k+ l- 1 ] += h[ j] [ k] * h[ i- j- 1 ] [ l] ;
for ( j= 1 ; j< N; j++ )
{
h[ i] [ j+ 1 ] += h[ i] [ j] / 10 ;
h[ i] [ j] %= 10 ;
}
}
while ( scanf ( "%d" , & n) != EOF )
{
i= N;
while ( h[ n] [ -- i] == 0 ) ;
for ( j= i; j> 0 ; j-- )
printf ( "%d" , h[ n] [ j] ) ;
printf ( "\n" ) ;
}
return 0 ;
}
组合数
# include <iostream>
# include <algorithm>
# define ll long long
using namespace std;
const ll maxn= 2 * 150007 ;
const ll mod= 998244353 ;
ll quick_mod ( ll a, ll b)
{
ll ans = 1 ;
a %= mod;
while ( b)
{
if ( b & 1 )
{
ans = ans * a % mod;
b-- ;
}
b >>= 1 ;
a = a * a % mod;
}
return ans;
}
ll C ( ll n, ll m)
{
if ( m > n) return 0 ;
ll ans = 1 ;
for ( int i= 1 ; i<= m; i++ )
{
ll a = ( n + i - m) % mod;
ll b = i % mod;
ans = ans * ( a * quick_mod ( b, mod- 2 ) % mod) % mod;
}
return ans;
}
ll Lucas ( ll n, ll m)
{
if ( m == 0 ) return 1 ;
return C ( n % mod, m % mod) * Lucas ( n / mod, m / mod) % mod;
}
const int N = 1e6 + 7 , mod = 1e9 + 7 ;
int n, m, k, t;
int inv[ N] ;
int fact[ N] , infact[ N] ;
void init ( int n)
{
fact[ 0 ] = infact[ 0 ] = inv[ 0 ] = inv[ 1 ] = 1 ;
for ( int i = 2 ; i <= n; ++ i)
inv[ i] = 1ll * ( mod - mod / i) * inv[ mod % i] % mod;
for ( int i = 1 ; i <= n; ++ i) {
fact[ i] = 1ll * fact[ i - 1 ] * i % mod;
infact[ i] = 1ll * infact[ i - 1 ] * inv[ i] % mod;
}
}
int C ( int n, int m)
{
if ( n < m) return 0 ;
if ( m == 0 || n == m) return 1 ;
return 1ll * fact[ n] * infact[ m] % mod * infact[ n - m] % mod;
}
中国剩余定理
# include <cstdio>
# include <cstring>
# include <cmath>
# include <algorithm>
# include <iostream>
using namespace std;
typedef long long ll;
ll e_gcd ( ll a, ll b, ll & x, ll & y) {
if ( b== 0 ) {
x= 1 , y= 0 ;
return a;
}
ll res= e_gcd ( b, a% b, y, x) ;
y-= ( a/ b) * x;
return res;
}
ll china ( ll pri[ ] , ll r[ ] , ll n) {
ll M= 1 , m, d, res= 0 ;
for ( int i= 0 ; i< n; i++ )
M*= pri[ i] ;
for ( int i= 0 ; i< n; i++ ) {
m= M/ pri[ i] ;
ll x, y;
d= e_gcd ( pri[ i] , m, x, y) ;
res= ( res+ y* m* r[ i] ) % M;
}
return ( res% M+ M) % M;
}
ll pri[ 20 ] , r[ 20 ] ;
int main ( ) {
int n;
while ( ~ scanf ( "%d" , & n) ) {
for ( int i= 0 ; i< n; i++ )
scanf ( "%lld %lld" , & pri[ i] , & r[ i] ) ;
ll ans= china ( pri, r, n) ;
printf ( "%lld\n" , ans) ;
}
}
素数筛
# include <bits/stdc++.h>
using namespace std;
const int maxn= 1e6 ;
int prime[ maxn] ;
int visit[ maxn] ;
void Prime ( )
{
memset ( visit, 0 , sizeof ( visit) ) ;
memset ( prime, 0 , sizeof ( visit) ) ;
visit[ 1 ] = 1 ;
for ( int i = 2 ; i <= maxn; i++ )
{
if ( ! visit[ i] )
{
prime[ ++ prime[ 0 ] ] = i;
}
for ( int j = 1 ; j <= prime[ 0 ] && i* prime[ j] <= maxn; j++ )
{
visit[ i* prime[ j] ] = 1 ;
if ( i % prime[ j] == 0 )
{
break ;
}
}
}
}
for ( int i= 2 ; i<= 10000000 ; i++ )
{
if ( ! f[ i] ) prm[ ++ cnt] = i, num[ i] = 1 ;
for ( int j= 1 ; j<= cnt && i* prm[ j] <= 10000000 ; j++ )
{
f[ i* prm[ j] ] = true ;
num[ i* prm[ j] ] = num[ i] + 1 ;
if ( i% prm[ j] == 0 ) break ;
}
}
void euler ( )
{
for ( int i = 1 ; i < N; i++ )
a[ i] = i;
for ( int i = 2 ; i < N; i += 2 )
a[ i] /= 2 ;
for ( int i = 3 ; i < N; i += 2 )
{
if ( a[ i] == i)
for ( int j = i; j < N; j += i)
{
if ( j % i == 0 )
a[ j] = a[ j] - a[ j] / i;
}
}
a[ 0 ] = 0 ;
for ( int i= 1 ; i< N; i++ )
{
a[ i] = a[ i- 1 ] + a[ i] ;
}
}
# include <iostream>
using namespace std;
typedef long long ll;
ll read ( string s, ll mod) {
ll x= 0 ;
for ( int i= 0 ; i< s. length ( ) ; i++ )
x= ( ( x<< 3 ) + ( x<< 1 ) + ( s[ i] ^ 48 ) ) % mod;
return ( x+ mod- 1 ) % mod;
}
ll pow ( ll s, ll n, ll mod) {
ll sum= 1 ;
while ( n) {
if ( n& 1 ) sum= sum* s% mod;
s= s* s% mod;
n>>= 1 ;
}
return sum;
}
ll phi ( ll x) {
ll t= x;
for ( int i= 2 ; i<= x/ i; i++ )
if ( x% i== 0 ) {
while ( x% i== 0 ) x/= i;
t= t* ( i- 1 ) / i;
}
if ( x> 1 ) t= t* ( x- 1 ) / x;
return t;
}
int main ( ) {
ll x, mod, n;
string nn;
cin>> x>> nn>> mod;
if ( x== 0 ) {
if ( nn== "1" ) cout<< 1 % mod;
else cout<< "0" ;
return 0 ;
}
x%= mod;
n= read ( nn, phi ( mod) ) ;
cout<< pow ( x% mod, n, mod) ;
}
逆元
void init ( ) {
fac[ 0 ] = 1 ;
for ( int i= 1 ; i<= MN; i++ )
fac[ i] = ( ll) fac[ i- 1 ] * i% mod;
inv[ MN] = qpow ( fac[ MN] , mod- 2 ) ;
for ( int i= MN- 1 ; i>= 0 ; i-- )
inv[ i] = ( ll) inv[ i+ 1 ] * ( i+ 1 ) % mod;
}
int C ( int n, int m) {
if ( m> n) return 0 ;
return ( ll) fac[ n] * inv[ m] % mod* inv[ n- m] % mod;
}
ll pow_mod ( ll a, ll b, ll p) {
ll ret = 1 ;
while ( b) {
if ( b & 1 ) ret = ( ret * a) % p;
a = ( a * a) % p;
b >>= 1 ;
}
return ret;
}
ll Fermat ( ll a, ll p) {
return pow_mod ( a, p- 2 , p) ;
}
质因数分解
bool vis[ N] ;
ll prime[ N] ;
int cnt= 0 ;
void primes ( )
{
for ( int i= 2 ; i<= N; i++ ) {
if ( vis[ i] ) {
continue ;
}
prime[ ++ cnt] = i;
for ( int j= 1 ; j<= N/ i; j++ ) {
vis[ i* j] = 1 ;
}
}
}
ll getprimefactor ( long long n)
{
ll ans= 0 ;
if ( n== 1 ) {
return 0 ;
}
if ( ! vis[ N] ) {
return 1 ;
}
for ( int i= 1 ; i<= cnt&& prime[ i] * prime[ i] <= n; i++ ) {
while ( n% prime[ i] == 0 ) {
ans++ ;
n/= prime[ i] ;
}
}
if ( n> 1 ) {
return ans+ 1 ;
}
return ans;
}
数据结构
ST表
void ST_init ( )
{
for ( int i= 1 ; i<= N; ++ i)
ST[ i] [ 0 ] = a[ i] ;
for ( int j= 1 ; j< 30 ; ++ j)
{
for ( int i= 1 ; i<= N; ++ i)
{
if ( i+ ( 1 << j) - 1 > N) break ;
ST[ i] [ j] = __gcd ( ST[ i] [ j- 1 ] , ST[ i+ ( 1 << ( j- 1 ) ) ] [ j- 1 ] ) ;
}
}
}
long long ST_query ( int s, int e)
{
int k= ( int ) ( ( log ( e- s+ 1.0 ) / log ( 2.0 ) ) ) ;
return __gcd ( ST[ s] [ k] , ST[ e- ( 1 << k) + 1 ] [ k] ) ;
}
void ST_preowrk ( )
{
for ( int i= 1 ; i<= n; i++ ) f[ i] [ 0 ] = a[ i] ;
int t= log ( n) / log ( 2 ) + 1 ;
for ( int j= 1 ; j< t; j++ ) {
for ( int i= 1 ; i<= n- ( 1 << j) + 1 ; i++ ) {
f[ i] [ j] = max ( f[ i] [ j- 1 ] , f[ i+ 1 << ( j- 1 ) ] [ j- 1 ] ) ;
}
}
}
ll ST_query ( int l, int r)
{
int k= log ( r- l+ 1 ) / log ( 2 ) ;
return max ( f[ l] [ k] , f[ r- ( 1 << k) + 1 ] [ k] ) ;
}
优先队列
# include <iostream>
# include <queue>
using namespace std;
int main ( )
{
int n;
while ( cin>> n)
{
int i, k, j, t1;
long long sum= 0 ;
priority_queue< int , vector< int > , greater< int > > p;
for ( i= 0 ; i< n; i++ )
{
cin>> k;
p. push ( k) ;
}
while ( p. size ( ) != 1 )
{
t1= p. top ( ) ;
p. pop ( ) ;
t1+= p. top ( ) ;
sum+= t1;
p. pop ( ) ;
p. push ( t1) ;
}
cout<< sum<< endl;
}
}
树状数组
int sum[ N] ;
int lowbit ( int x)
{
return x & ( - x) ;
}
void add ( int x, int num)
{
while ( x <= n)
{
sum[ x] += num;
x += lowbit ( x) ;
}
}
int ask ( int x)
{
int res = 0 ;
while ( x > 0 )
{
res += sum[ x] ;
x -= lowbit ( x) ;
}
return res;
}
单调栈
int tot= 0 ;
h[ m+ 1 ] = 0 ;
for ( int j= 1 ; j<= m+ 1 ; j++ ) {
while ( tot&& h[ que[ tot] ] > h[ j] ) {
ans= max ( ans, ( j- 1 - que[ tot- 1 ] ) [ que[ tot] ] ) ;
tot-- ;
}
que[ ++ tot] = j;
}
线段树
# include <cstdio>
# include <cstring>
# include <algorithm>
using namespace std;
const int N = 100005 ;
const int INF = 0x3f3f3f3f ;
int s[ N << 2 ] , lc[ N << 2 ] , rc[ N << 2 ] ;
int n, m, num[ N] ;
void build ( int u , int l , int r) {
lc[ u] = l;
rc[ u] = r;
if ( l == r) {
s[ u] = num[ l] ;
return ;
}
int mid = ( l + r) / 2 ;
build ( u * 2 , l , mid) ;
build ( u * 2 + 1 , mid + 1 , r) ;
s[ u] = min ( s[ u * 2 ] , s[ u * 2 + 1 ] ) ;
}
void change ( int u , int x , int v) {
if ( lc[ u] == x && rc[ u] == x) {
s[ u] = v;
return ;
}
int mid = ( lc[ u] + rc[ u] ) / 2 ;
if ( x <= mid)
change ( u * 2 , x , v) ;
else
change ( u * 2 + 1 , x , v) ;
s[ u] = min ( s[ u * 2 ] , s[ u * 2 + 1 ] ) ;
}
int query ( int u , int l , int r) {
int res = INF;
if ( l <= lc[ u] && r >= rc[ u] ) {
return s[ u] ;
}
int mid = ( lc[ u] + rc[ u] ) / 2 ;
if ( l <= mid)
res = min ( res , query ( u * 2 , l , r) ) ;
if ( r > mid)
res = min ( res , query ( u * 2 + 1 , l , r) ) ;
return res;
}
# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
# define lowbit ( x) ( ( x) & ( - x) )
const ll mod = 998244353 ;
ll powmod ( ll a, ll b)
{
ll res= 1 ; a%= mod;
while ( b) {
if ( b& 1 ) {
res= res* a% mod;
}
a= a* a% mod;
b>>= 1 ;
}
return res;
}
const int N = 1e5 + 50 ;
int n, m;
struct node
{
int l, r;
ll x, sum;
int lazy; int flag;
} tree[ N<< 2 ] ;
void push_up ( int p)
{
tree[ p] . sum= ( tree[ p<< 1 ] . sum+ tree[ p<< 1 | 1 ] . sum) % mod;
tree[ p] . flag= ( tree[ p<< 1 ] . flag& tree[ p<< 1 | 1 ] . flag) ;
}
void push_down ( int p)
{
if ( tree[ p] . lazy== 0 ) return ;
tree[ p<< 1 ] . lazy+= tree[ p] . lazy;
tree[ p<< 1 | 1 ] . lazy+= tree[ p] . lazy;
tree[ p<< 1 ] . sum= ( tree[ p<< 1 ] . sum* powmod ( 2 , tree[ p] . lazy) ) % mod;
tree[ p<< 1 | 1 ] . sum= ( tree[ p<< 1 | 1 ] . sum* powmod ( 2 , tree[ p] . lazy) ) % mod;
tree[ p] . lazy= 0 ;
}
void build_tree ( int l, int r, int p)
{
tree[ p] . l= l, tree[ p] . r= r;
tree[ p] . lazy= tree[ p] . flag= 0 ;
if ( l== r) {
scanf ( "%lld" , & tree[ p] . x) ;
tree[ p] . sum= tree[ p] . x;
if ( lowbit ( tree[ p] . x) == tree[ p] . x)
tree[ p] . flag= 1 ;
return ;
}
int mid= l+ r>> 1 ;
build_tree ( l, mid, p<< 1 ) ;
build_tree ( mid+ 1 , r, p<< 1 | 1 ) ;
push_up ( p) ;
}
void update_tree ( int l, int r, int p)
{
if ( l<= tree[ p] . l&& tree[ p] . r<= r&& tree[ p] . flag) {
tree[ p] . sum= ( tree[ p] . sum* 2 ) % mod;
tree[ p] . lazy++ ;
return ;
}
if ( tree[ p] . l== tree[ p] . r) {
tree[ p] . x= tree[ p] . sum= tree[ p] . sum+ lowbit ( tree[ p] . sum) ;
if ( lowbit ( tree[ p] . x) == tree[ p] . x) {
tree[ p] . flag= 1 ;
}
return ;
}
push_down ( p) ;
int mid= ( tree[ p] . l+ tree[ p] . r) >> 1 ;
if ( l<= mid) update_tree ( l, r, p<< 1 ) ;
if ( mid< r) update_tree ( l, r, p<< 1 | 1 ) ;
push_up ( p) ;
}
ll ask_sum ( int l, int r, int p)
{
if ( l<= tree[ p] . l&& tree[ p] . r<= r) {
return tree[ p] . sum;
}
ll res= 0 ;
push_down ( p) ;
int mid= ( tree[ p] . l+ tree[ p] . r) >> 1 ;
if ( l<= mid) {
res= ( res+ ask_sum ( l, r, p<< 1 ) ) % mod;
}
if ( mid< r) {
res= ( res+ ask_sum ( l, r, p<< 1 | 1 ) ) % mod;
}
return res;
}
void solve ( )
{
scanf ( "%d" , & n) ;
build_tree ( 1 , n, 1 ) ;
scanf ( "%d" , & m) ;
int op, l, r;
for ( int i= 1 ; i<= m; i++ ) {
scanf ( "%d%d%d" , & op, & l, & r) ;
if ( op== 1 ) {
update_tree ( l, r, 1 ) ;
}
else {
printf ( "%lld\n" , ask_sum ( l, r, 1 ) ) ;
}
}
}
int main ( )
{
int t; scanf ( "%d" , & t) ;
while ( t-- ) {
solve ( ) ;
}
}
# include <bits/stdc++.h>
using namespace std;
const int maxn= 100010 ;
int a[ maxn+ 2 ] ;
struct tree {
int l, r;
long long pre, add;
} t[ 4 * maxn+ 2 ] ;
void bulid ( int p, int l, int r) {
t[ p] . l= l; t[ p] . r= r;
if ( l== r) {
t[ p] . pre= a[ l] ;
return ;
}
int mid= l+ r>> 1 ;
bulid ( p* 2 , l, mid) ;
bulid ( p* 2 + 1 , mid+ 1 , r) ;
t[ p] . pre= t[ p* 2 ] . pre+ t[ p* 2 + 1 ] . pre;
}
void spread ( int p) {
if ( t[ p] . add) {
t[ p* 2 ] . pre+= t[ p] . add* ( t[ p* 2 ] . r- t[ p* 2 ] . l+ 1 ) ;
t[ p* 2 + 1 ] . pre+= t[ p] . add* ( t[ p* 2 + 1 ] . r- t[ p* 2 + 1 ] . l+ 1 ) ;
t[ p* 2 ] . add+= t[ p] . add;
t[ p* 2 + 1 ] . add+= t[ p] . add;
t[ p] . add= 0 ;
}
}
void change ( int p, int x, int y, int z) {
if ( x<= t[ p] . l && y>= t[ p] . r) {
t[ p] . pre+= ( long long ) z* ( t[ p] . r- t[ p] . l+ 1 ) ;
t[ p] . add+= z;
return ;
}
spread ( p) ;
int mid= t[ p] . l+ t[ p] . r>> 1 ;
if ( x<= mid) change ( p* 2 , x, y, z) ;
if ( y> mid) change ( p* 2 + 1 , x, y, z) ;
t[ p] . pre= t[ p* 2 ] . pre+ t[ p* 2 + 1 ] . pre;
}
long long ask ( int p, int x, int y) {
if ( x<= t[ p] . l && y>= t[ p] . r) return t[ p] . pre;
spread ( p) ;
int mid= t[ p] . l+ t[ p] . r>> 1 ;
long long ans= 0 ;
if ( x<= mid) ans+= ask ( p* 2 , x, y) ;
if ( y> mid) ans+= ask ( p* 2 + 1 , x, y) ;
return ans;
}
int main ( ) {
int n, m;
scanf ( "%d%d" , & n, & m) ;
for ( int i= 1 ; i<= n; i++ )
scanf ( "%d" , & a[ i] ) ;
bulid ( 1 , 1 , n) ;
for ( int i= 1 ; i<= m; i++ )
{
int q, x, y, z;
scanf ( "%d" , & q) ;
if ( q== 1 ) {
scanf ( "%d%d%d" , & x, & y, & z) ;
change ( 1 , x, y, z) ;
}
else {
scanf ( "%d%d" , & x, & y) ;
cout<< ask ( 1 , x, y) << endl;
}
}
return 0 ;
}
# include <bits/stdc++.h>
using namespace std;
# define maxn 200005
int min ( int a, int b)
{
return a> b ? b : a;
}
int tree[ 4 * maxn] ;
void pushup ( int i)
{
tree[ i] = min ( tree[ i << 1 ] , tree[ i << 1 | 1 ] ) ;
}
void build ( int i, int l, int r)
{
if ( l == r)
{
scanf ( "%lld" , & tree[ i] ) ;
return ;
}
int mid = ( l + r) / 2 ;
build ( i << 1 , l, mid) ;
build ( i << 1 | 1 , mid + 1 , r) ;
pushup ( i) ;
}
void update ( int i, int l, int r, int x, int val)
{
if ( l == r)
{
tree[ i] = val;
return ;
}
int mid = ( l + r) / 2 ;
if ( x <= mid) update ( i << 1 , l, mid, x, val) ;
else update ( i << 1 | 1 , mid + 1 , r, x, val) ;
pushup ( i) ;
}
int query ( int i, int l, int r, int x, int y)
{
if ( x <= l && r <= y)
return tree[ i] ;
int minn = 9999999 ;
int mid = ( l + r) / 2 ;
if ( x <= mid) minn = min ( minn, query ( i << 1 , l, mid, x, y) ) ;
if ( y> mid) minn = min ( minn, query ( i << 1 | 1 , mid + 1 , r, x, y) ) ;
return minn;
}
int main ( )
{
int n, m;
int b, c;
char a;
while ( scanf ( "%d%d" , & n, & m) != - 1 )
{
build ( 1 , 1 , n) ;
while ( m-- )
{
scanf ( " %c%d%d" , & a, & b, & c) ;
if ( a == 'Q' )
printf ( "%d\n" , query ( 1 , 1 , n, b, c) ) ;
else
update ( 1 , 1 , n, b, c) ;
}
}
return 0 ;
}
# include <bits/stdc++.h>
using namespace std;
# define maxn 200005
int tree[ 4 * maxn] ;
void pushup ( int i)
{
tree[ i] = max ( tree[ i << 1 ] , tree[ i << 1 | 1 ] ) ;
}
void build ( int i, int l, int r)
{
if ( l == r)
{
tree[ i] = 0 ;
return ;
}
int mid = ( l + r) / 2 ;
build ( i << 1 , l, mid) ;
build ( i << 1 | 1 , mid + 1 , r) ;
pushup ( i) ;
}
void update ( int i, int l, int r, int x, int val)
{
if ( l == r)
{
tree[ i] = val;
return ;
}
int mid = ( l + r) / 2 ;
if ( x <= mid) update ( i << 1 , l, mid, x, val) ;
else update ( i << 1 | 1 , mid + 1 , r, x, val) ;
pushup ( i) ;
}
int query ( int i, int l, int r, int x, int y)
{
if ( x <= l && r <= y)
return tree[ i] ;
int maxm = 0 ;
int mid = ( l + r) / 2 ;
if ( x <= mid) maxm = max ( maxm, query ( i << 1 , l, mid, x, y) ) ;
if ( y> mid) maxm = max ( maxm, query ( i << 1 | 1 , mid + 1 , r, x, y) ) ;
return maxm;
}
int main ( )
{
int n, m;
int b, c;
char a;
while ( ~ scanf ( "%d%d" , & n, & m) )
{
build ( 1 , 1 , n) ;
while ( m-- )
{
scanf ( " %c%d%d" , & a, & b, & c) ;
if ( a == 'Q' )
printf ( "%d\n" , query ( 1 , 1 , n, b, c) ) ;
else
update ( 1 , 1 , n, b, c) ;
}
}
}
主席树
# include <algorithm>
# include <cstdio>
# include <cstring>
using namespace std;
const int maxn = 1e5 ;
int tot, n, m;
int sum[ ( maxn << 5 ) + 10 ] , rt[ maxn + 10 ] , ls[ ( maxn << 5 ) + 10 ] ,
rs[ ( maxn << 5 ) + 10 ] ;
int a[ maxn + 10 ] , ind[ maxn + 10 ] , len;
inline int getid ( const int & val) {
return lower_bound ( ind + 1 , ind + len + 1 , val) - ind;
}
int build ( int l, int r) {
int root = ++ tot;
if ( l == r) return root;
int mid = l + r >> 1 ;
ls[ root] = build ( l, mid) ;
rs[ root] = build ( mid + 1 , r) ;
return root;
}
int update ( int k, int l, int r, int root) {
int dir = ++ tot;
ls[ dir] = ls[ root] , rs[ dir] = rs[ root] , sum[ dir] = sum[ root] + 1 ;
if ( l == r) return dir;
int mid = l + r >> 1 ;
if ( k <= mid)
ls[ dir] = update ( k, l, mid, ls[ dir] ) ;
else
rs[ dir] = update ( k, mid + 1 , r, rs[ dir] ) ;
return dir;
}
int query ( int u, int v, int l, int r, int k) {
int mid = l + r >> 1 ,
x = sum[ ls[ v] ] - sum[ ls[ u] ] ;
if ( l == r) return l;
if ( k <= x)
return query ( ls[ u] , ls[ v] , l, mid, k) ;
else
return query ( rs[ u] , rs[ v] , mid + 1 , r, k - x) ;
}
inline void init ( ) {
scanf ( "%d%d" , & n, & m) ;
for ( int i = 1 ; i <= n; ++ i) scanf ( "%d" , a + i) ;
memcpy ( ind, a, sizeof ind) ;
sort ( ind + 1 , ind + n + 1 ) ;
len = unique ( ind + 1 , ind + n + 1 ) - ind - 1 ;
rt[ 0 ] = build ( 1 , len) ;
for ( int i = 1 ; i <= n; ++ i) rt[ i] = update ( getid ( a[ i] ) , 1 , len, rt[ i - 1 ] ) ;
}
int l, r, k;
inline void work ( ) {
while ( m-- ) {
scanf ( "%d%d%d" , & l, & r, & k) ;
printf ( "%d\n" , ind[ query ( rt[ l - 1 ] , rt[ r] , 1 , len, k) ] ) ;
}
}
int main ( ) {
init ( ) ;
work ( ) ;
return 0 ;
}
# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 7 ;
int root[ MAXN] , n, q, size, num;
ll a[ MAXN] , s[ MAXN] , b[ MAXN] ;
struct HJT_tree {
int l, r, cnt;
ll sum, val;
} tree[ MAXN* 40 ] ;
void build ( int & now, int l, int r) {
now = ++ size;
tree[ now] . cnt = tree[ now] . sum = tree[ now] . val = 0 ;
if ( l == r) return ;
int mid = ( l+ r) >> 1 ;
build ( tree[ now] . l, l, mid) ;
build ( tree[ now] . r, mid+ 1 , r) ;
}
void modify ( int & now, int pre, int l, int r, int p, int val) {
tree[ now = ++ size] = tree[ pre] ;
tree[ now] . cnt++ , tree[ now] . sum += val;
if ( l == r) {
tree[ now] . val = val;
return ;
}
int mid = ( l+ r) >> 1 ;
if ( p <= mid) modify ( tree[ now] . l, tree[ pre] . l, l, mid, p, val) ;
else modify ( tree[ now] . r, tree[ pre] . r, mid+ 1 , r, p, val) ;
}
ll query ( int now, int pre, int l, int r, int k) {
if ( l == r) return tree[ now] . val * k;
int mid = ( l+ r) >> 1 ;
int tmp = tree[ tree[ now] . r] . cnt - tree[ tree[ pre] . r] . cnt;
if ( tmp >= k) return query ( tree[ now] . r, tree[ pre] . r, mid+ 1 , r, k) ;
else return query ( tree[ now] . l, tree[ pre] . l, l, mid, k- tmp) +
tree[ tree[ now] . r] . sum - tree[ tree[ pre] . r] . sum;
}
int getid ( ll x) { return lower_bound ( b+ 1 , b+ 1 + num, x) - b; }
int main ( ) {
int T;
scanf ( "%d" , & T) ;
while ( T-- ) {
memset ( root, 0 , sizeof ( root) ) ;
size = 0 ;
scanf ( "%d" , & n) ;
for ( int i = 1 ; i <= n; i ++ ) {
scanf ( "%lld" , & a[ i] ) ;
b[ i] = a[ i] ;
s[ i] = s[ i- 1 ] + ( 1ll * i* i) ;
}
sort ( b+ 1 , b+ 1 + n) ;
num = unique ( b+ 1 , b+ 1 + n) - b- 1 ;
build ( root[ 0 ] , 1 , num) ;
for ( int i = 1 ; i <= n; i ++ ) {
int p = getid ( a[ i] ) ;
modify ( root[ i] , root[ i- 1 ] , 1 , num, p, a[ i] ) ;
}
scanf ( "%d" , & q) ;
int l, r, k;
while ( q-- ) {
scanf ( "%d%d%d" , & l, & r, & k) ;
ll ans = query ( root[ r] , root[ l- 1 ] , 1 , num, k) ;
ans += s[ r- l+ 1 ] ;
printf ( "%lld\n" , ans) ;
}
}
return 0 ;
}
树上倍增求LCA
# include <cstdio>
# include <cstring>
# include <algorithm>
using namespace std;
const int MAXN= 1000010 ;
inline void read ( int & n)
{
char c= getchar ( ) ; bool flag= 0 ; n= 0 ;
while ( c< '0' || c> '9' ) c== '-' ? flag= 1 , c= getchar ( ) : c= getchar ( ) ;
while ( c>= '0' && c<= '9' ) n= n* 10 + c- 48 , c= getchar ( ) ; flag== 1 ? n= - n: n= n;
}
struct node
{
int v, nxt;
} edge[ MAXN] ;
int head[ MAXN] ;
int num= 1 ;
inline void add_edge ( int x, int y)
{
edge[ num] . v= y;
edge[ num] . nxt= head[ x] ;
head[ x] = num++ ;
}
int f[ MAXN] [ 21 ] ;
int deep[ MAXN] ;
int n, m, root;
void dfs ( int now)
{
for ( int i= head[ now] ; i!= - 1 ; i= edge[ i] . nxt)
if ( ! deep[ edge[ i] . v] )
deep[ edge[ i] . v] = deep[ now] + 1 , f[ edge[ i] . v] [ 0 ] = now, dfs ( edge[ i] . v) ;
}
void PRE ( )
{
for ( int i= 1 ; i<= 19 ; i++ )
for ( int j= 1 ; j<= n; j++ )
f[ j] [ i] = f[ f[ j] [ i- 1 ] ] [ i- 1 ] ;
}
int LCA ( int x, int y)
{
if ( deep[ x] < deep[ y] ) swap ( x, y) ;
for ( int i= 19 ; i>= 0 ; i-- )
if ( deep[ f[ x] [ i] ] >= deep[ y] )
x= f[ x] [ i] ;
if ( x== y) return x;
for ( int i= 19 ; i>= 0 ; i-- )
if ( f[ x] [ i] != f[ y] [ i] )
x= f[ x] [ i] , y= f[ y] [ i] ;
return f[ x] [ 0 ] ;
}
int main ( )
{
memset ( head, - 1 , sizeof ( head) ) ;
read ( n) ; read ( m) ; read ( root) ;
for ( int i= 1 ; i<= n- 1 ; i++ )
{
int x, y; read ( x) ; read ( y) ;
add_edge ( x, y) ;
add_edge ( y, x) ;
}
deep[ root] = 1 ;
dfs ( root) ;
PRE ( ) ;
for ( int i= 1 ; i<= m; i++ )
{
int x, y;
read ( x) ; read ( y) ;
printf ( "%d\n" , LCA ( x, y) ) ;
}
return 0 ;
}
树链剖分
void dfs1 ( int o) {
son[ o] = - 1 ;
siz[ o] = 1 ;
for ( int j = h[ o] ; j; j = nxt[ j] )
if ( ! dep[ p[ j] ] ) {
dep[ p[ j] ] = dep[ o] + 1 ;
fa[ p[ j] ] = o;
dfs1 ( p[ j] ) ;
siz[ o] += siz[ p[ j] ] ;
if ( son[ o] == - 1 || siz[ p[ j] ] > siz[ son[ o] ] ) son[ o] = p[ j] ;
}
}
void dfs2 ( int o, int t) {
top[ o] = t;
cnt++ ;
dfn[ o] = cnt;
rnk[ cnt] = o;
if ( son[ o] == - 1 ) return ;
dfs2 ( son[ o] , t) ;
for ( int j = h[ o] ; j; j = nxt[ j] )
if ( p[ j] != son[ o] && p[ j] != fa[ o] ) dfs2 ( p[ j] , p[ j] ) ;
}
莫队
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <iostream>
# include <cmath>
# include <stack>
# include <queue>
using namespace std;
typedef long long ll;
const int maxn = 100010 ;
int n, m, blo;
int l= 1 , r= 0 ;
int c[ maxn] , cnt[ maxn] , pos[ maxn] ;
ll res= 0 ;
struct Q {
int l, r, id;
} q[ maxn] ;
struct Ans {
ll a, b;
} ans[ maxn] ;
bool cmp ( Q a, Q b) {
if ( pos[ a. l] == pos[ b. l] ) return a. r< b. r;
return a. l< b. l;
}
void add ( int i) {
res-= 1ll * cnt[ c[ i] ] * cnt[ c[ i] ] ;
++ cnt[ c[ i] ] ;
res+= 1ll * cnt[ c[ i] ] * cnt[ c[ i] ] ;
}
void del ( int i) {
res-= 1ll * cnt[ c[ i] ] * cnt[ c[ i] ] ;
-- cnt[ c[ i] ] ;
res+= 1ll * cnt[ c[ i] ] * cnt[ c[ i] ] ;
}
ll gcd ( ll a, ll b) {
if ( a< b) swap ( a, b) ;
return b== 0 ? a: gcd ( b, a% b) ;
}
ll read ( ) { ll s= 0 , f= 1 ; char ch= getchar ( ) ; while ( ch< '0' || ch> '9' ) { if ( ch== '-' ) f= - 1 ; ch= getchar ( ) ; } while ( ch>= '0' && ch<= '9' ) { s= s* 10 + ch- '0' ; ch= getchar ( ) ; } return s* f; }
int main ( ) {
n= read ( ) , m= read ( ) ;
blo= sqrt ( n) ;
for ( int i= 1 ; i<= n; i++ ) c[ i] = read ( ) , pos[ i] = ( i- 1 ) / blo+ 1 ;
for ( int i= 1 ; i<= m; i++ ) {
q[ i] . l= read ( ) , q[ i] . r= read ( ) ;
q[ i] . id= i;
}
sort ( q+ 1 , q+ 1 + m, cmp) ;
for ( int i= 1 ; i<= m; i++ ) {
while ( l< q[ i] . l) { del ( l) ; l++ ; }
while ( l> q[ i] . l) { add ( l- 1 ) ; l-- ; }
while ( r< q[ i] . r) { add ( r+ 1 ) ; r++ ; }
while ( r> q[ i] . r) { del ( r) ; r-- ; }
if ( q[ i] . l== q[ i] . r) {
ans[ q[ i] . id] = ( Ans) { 0 , 1 } ;
continue ;
}
ans[ q[ i] . id] = ( Ans) { res- ( r- l+ 1 ) , 1ll * ( r- l+ 1 ) * ( r- l) } ;
}
for ( int i= 1 ; i<= m; i++ ) {
ll g= gcd ( ans[ i] . a, ans[ i] . b) ;
printf ( "%lld/%lld\n" , ans[ i] . a/ g, ans[ i] . b/ g) ;
}
return 0 ;
}
字符串
字典树
# include <bits/stdc++.h>
using namespace std;
# define PII pair< int , int >
typedef long long ll;
const int maxn = 1e3 + 7 ;
const int N = 4e6 + 7 ;
char mp[ maxn] [ maxn] ;
char str[ maxn] , t[ maxn] ;
int n, m;
int trie[ N] [ 26 ] , idx, val[ N] ;
void insert ( char * s, int x)
{
int p = 0 , len = strlen ( s) ;
for ( int i = 0 ; i < len; i ++ ) {
int ch = s[ i] - 'a' ;
if ( ! trie[ p] [ ch] ) trie[ p] [ ch] = ++ idx;
p = trie[ p] [ ch] ;
}
val[ p] = x;
}
int query ( char * s)
{
int p = 0 , len = strlen ( s) ;
for ( int i = 0 ; i < len; i ++ ) {
int ch = s[ i] - 'a' ;
p = trie[ p] [ ch] ;
if ( ! p) return - 1 ;
}
if ( val[ p] ) return val[ p] ;
else return - 1 ;
}
void init ( )
{
for ( int i = 0 ; i <= idx; i ++ ) {
memset ( trie[ i] , 0 , sizeof ( trie[ i] ) ) ;
val[ i] = 0 ;
}
idx = 0 ;
}
int main ( )
{
int tt; scanf ( "%d" , & tt) ;
while ( tt-- ) {
init ( ) ;
scanf ( "%d%d" , & n, & m) ;
for ( int i = 1 ; i <= n; i++ ) {
scanf ( "%s" , mp[ i] + 1 ) ;
}
while ( m-- ) {
int x; scanf ( "%s%d" , str, & x) ;
insert ( str, x) ;
}
int flag = 0 ; ll sum = 0 ;
for ( int i = 1 ; i <= n; i++ ) {
for ( int j = 1 ; j <= n; j++ ) {
int len = 0 ;
if ( mp[ i] [ j] == '#' ) continue ;
while ( mp[ i] [ j] != '#' && j <= n) {
t[ len++ ] = mp[ i] [ j] ;
j++ ;
}
t[ len] = '\0' ;
int ans = query ( t) ;
if ( ans == - 1 ) flag = 1 ;
else sum += ans;
}
}
for ( int j= 1 ; j<= n; j++ ) {
for ( int i= 1 ; i<= n; i++ ) {
int len = 0 ;
if ( mp[ i] [ j] == '#' ) continue ;
while ( mp[ i] [ j] != '#' && i <= n) {
t[ len++ ] = mp[ i] [ j] ;
i++ ;
}
t[ len] = '\0' ;
int ans = query ( t) ;
if ( ans == - 1 ) flag = 1 ;
else sum += ans;
}
}
if ( flag) printf ( "-1\n" ) ;
else printf ( "%lld\n" , sum) ;
}
}
字符串hash
# include <iostream>
# include <algorithm>
using namespace std;
typedef unsigned long long ULL;
const int N= 1e6 + 10 , M= 131 ;
int n, m;
char str[ N] ;
ULL p[ N] , h[ N] ;
ULL get ( int l, int r)
{
return h[ r] - h[ l- 1 ] * p[ r- l+ 1 ] ;
}
int main ( )
{
cin>> n>> m;
cin>> str+ 1 ;
p[ 0 ] = 1 ;
for ( int i= 1 ; i<= n; i++ )
{
h[ i] = h[ i- 1 ] * M+ str[ i] ;
p[ i] = p[ i- 1 ] * M;
}
while ( m-- )
{
int l1, r1, l2, r2;
cin>> l1>> r1>> l2>> r2;
if ( get ( l1, r1) == get ( l2, r2) ) puts ( "Yes" ) ;
else
puts ( "No" ) ;
}
return 0 ;
}
图论
图的连通子图
# include <bits/stdc++.h>
const int N= 1005 ;
using namespace std;
vector< int > t[ N] ;
int vis[ N] = { 0 } ;
void dfs ( int k)
{
for ( int i= 0 ; i< t[ k] . size ( ) ; i++ )
{
if ( vis[ t[ k] [ i] ] == 0 )
{ vis[ t[ k] [ i] ] = 1 ;
dfs ( t[ k] [ i] ) ;
}
}
}
int main ( )
{
int n, m;
cin>> n>> m;
int a, b;
for ( int i= 1 ; i<= m; i++ )
{
cin>> a>> b;
t[ a] . push_back ( b) ;
t[ b] . push_back ( a) ;
}
int ans= 0 ;
for ( int i= 1 ; i<= n; i++ )
{
if ( vis[ i] == 0 )
{
vis[ i] = 1 ;
dfs ( i) ;
ans++ ;
}
}
cout<< ans<< endl;
return 0 ;
}
# include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5 + 3 ;
int edge[ maxn] [ maxn] ;
vector< int > t[ maxn] ;
int pre[ maxn] , root[ maxn] ;
void init ( int nn)
{
for ( int i = 1 ; i <= nn; i++ )
pre[ i] = i;
}
int find ( int x)
{
int f = x;
while ( x != pre[ x] )
x = pre[ x] ;
int j;
while ( f != pre[ f] )
{
j = f;
f = pre[ f] ;
pre[ j] = x;
}
return x;
}
void merge ( int a, int b)
{
int t1, t2;
t1 = find ( a) ;
t2 = find ( b) ;
if ( t1 != t2)
{
pre[ t2] = t1;
}
}
int block ( int nn)
{
int ans = 0 ;
for ( int i = 1 ; i <= nn; i++ )
root[ pre[ i] ] = 1 ;
for ( int i = 1 ; i <= nn; i++ )
ans += root[ i] ;
return ans;
}
int main ( )
{
int n, m;
cin >> n >> m;
init ( n) ;
for ( int i = 1 ; i <= m; i++ )
{
int a, b;
scanf ( "%d%d" , & a, & b) ;
t[ a] . push_back ( b) ;
t[ b] . push_back ( a) ;
}
for ( int i = 1 ; i <= n; i++ )
{
vector< int > :: iterator it;
for ( it= t[ i] . begin ( ) ; it!= t[ i] . size ( ) )
printf ( "%d" , block ( n) ) ;
}
}