C
n场比赛,k场结果已知,其中, |a赢的次数 - b赢的次数| = k1 , |c赢的次数 - d赢的次数| = k2
求是否存在方案使得,a,b,c,d赢的次数相同。
f(x)记x赢的次数
有 f(a) + f(b) + f(c) + f(d) = k
|f(a) - f(b)| = d1
|f(c) - f(d)| = d2
三个方程三个未知数,且系数矩阵行列式不为0,存在唯一解。
若某解 > n/3 则没有这样的方案
typedef long long LL ;
LL n , k , d1 , d2 ;
LL A(LL a[4][4]){
return a[1][1]*a[2][2]*a[3][3]
+ a[1][2]*a[2][3]*a[3][1]
+ a[1][3]*a[2][1]*a[3][2]
- a[1][3]*a[2][2]*a[3][1]
- a[1][2]*a[2][1]*a[3][3]
- a[1][1]*a[3][2]*a[2][3] ;
}
int gao(LL a[4][4] , LL y[4]){
LL mu = A(a) ;
LL b[4][4] , zi ;
LL x ;
for(int i = 1 ; i <= 3 ; i++){
for(int j = 1 ; j <= 3 ; j++) b[i][j] = a[i][j] ;
}
for(int i = 1 ; i <= 3 ; i++) b[i][1] = y[i] ;
zi = A(b) ;
if(zi % mu ) return 0 ;
x = zi / mu ;
if(x > n || x < 0) return 0 ;
for(int i = 1 ; i <= 3 ; i++){
for(int j = 1 ; j <= 3 ; j++) b[i][j] = a[i][j] ;
}
for(int i = 1 ; i <= 3 ; i++) b[i][2] = y[i] ;
zi = A(b) ;
if(zi % mu ) return 0 ;
x = zi / mu ;
if(x > n || x < 0) return 0 ;
for(int i = 1 ; i <= 3 ; i++){
for(int j = 1 ; j <= 3 ; j++) b[i][j] = a[i][j] ;
}
for(int i = 1 ; i <= 3 ; i++) b[i][3] = y[i] ;
zi = A(b) ;
if(zi % mu ) return 0 ;
x = zi / mu ;
if(x > n || x < 0) return 0 ;
return 1 ;
}
int main(){
int t ; cin>>t ;
LL a[4][4] , y[4] ;
while(t--){
cin>>n>>k>>d1>>d2 ;
if(n % 3){
puts("no") ;
continue ;
}
n /= 3 ;
a[1][1] = 1 , a[1][2] = 1 , a[1][3] = 1 ;
a[2][1] = 1 , a[2][2] = -1 , a[2][3] = 0 ;
a[3][1] = 0 , a[3][2] = 1 , a[3][3] = -1 ;
y[1] = k , y[2] = d1 , y[3] = d2 ;
if(gao(a , y) ){
puts("yes") ;
continue ;
}
y[1] = k , y[2] = -d1 , y[3] = d2 ;
if(gao(a , y) ){
puts("yes") ;
continue ;
}
y[1] = k , y[2] = d1 , y[3] = -d2 ;
if(gao(a , y) ){
puts("yes") ;
continue ;
}
y[1] = k , y[2] = -d1 , y[3] = -d2 ;
if(gao(a , y) ){
puts("yes") ;
continue ;
}
puts("no") ;
}
return 0 ;
}
连续相同的字母可以压缩为这个字母 , 如abbbbba 压缩后为aba
求串的子串,满足压缩后为回文串。 这样的字串长度为奇数,偶数 的总数。
某串压缩之后一定为abababab...
或者 babababa....
我们字需要统计奇数位,偶数位上 a , b 出现的次数
那么子串为偶数, 只需 奇数位a 取一个 * 偶数位a取一个
+ 奇数位b 取一个 * 偶数位b取一个
子串为奇数数, 只需 奇数位a 取2个 总数
+ 偶数位a取2个 总数
+ 奇数位b 取2个 总数
+ 偶数位b取2个 总数
+ 串长
typedef long long LL ;
const int maxn = 100008 ;
char str[maxn] ;
LL c[2][2] ;
LL g(LL x){
return x >= 2 ? x * (x-1) / 2 : 0 ;
}
int main(){
while(scanf("%s" , str+1) != EOF){
LL n = strlen(str+1) ;
memset(c , 0 , sizeof(c)) ;
for(LL i = 1 ; i <= n ; i++)
c[i&1][str[i] - 'a']++ ;
LL a = c[1][0] * c[0][0] + c[1][1] * c[0][1] ;
LL b = g(c[0][0]) + g(c[0][1]) + g(c[1][0]) + g(c[1][1]) + n ;
cout<< a << " " << b << endl ;
}
return 0 ;
}