14 篇文章 0 订阅
44 篇文章 0 订阅

# T1：分数转换

## 题目

Time limit: 1.5 seconds
Memory limit: 512 megabytes

Input

Output

Scoring

Example
frac.in
5
-0.0
0.[3]
1926.0[817]
1.00
-123.456
frac.out
0/1
1/3
19241557/9990
1/1
-15432/125

## 题解

1.首先对于没有循环节的输入，如

123.1025

2.只有整数和循环节的输入，如

123.[7851]

.3.整数，小数，循环节都有的输入，如样例

1926.0[817]

## 代码实现

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define LL long long
#define MAXN 20
int T;
char s[MAXN];

LL gcd ( LL x, LL y ) {
if ( ! y )
return x;
return gcd ( y, x % y );
}

int main() {
scanf ( "%d", &T );
while ( T -- ) {
scanf ( "%s", s );
int len = strlen ( s );
bool flag1 = 0, flag2 = 0;
int digit = 0;
LL cnt1 = 0, cnt2 = 0, cnt3 = 0;
LL tot1 = 0, tot2 = 0, tot3 = 0;

while ( digit < len && s[digit] == '-' ) {
flag1 = 1;
digit ++;
}
while ( digit < len && s[digit] != '.' ) {
cnt1 = ( cnt1 << 3 ) + ( cnt1 << 1 ) + ( s[digit] - '0' );
digit ++;
tot1 ++;
}
if ( s[digit] == '.' )
digit ++;
while ( digit < len && s[digit] != '[' ) {
cnt2 = ( cnt2 << 3 ) + ( cnt2 << 1 ) + ( s[digit] - '0' );
digit ++;
tot2 ++;
}
if ( s[digit] == '[' ) {
digit ++;
flag2 = 1;
}
while ( digit < len && s[digit] != ']' ) {
cnt3 = ( cnt3 << 3 ) + ( cnt3 << 1 ) + ( s[digit] - '0' );
digit ++;
tot3 ++;
}

LL N = ( LL ) pow ( 10, tot2 );
LL d, fenzi, fenmu;
if ( tot2 != 0 ) {
d = gcd ( cnt1 * N + cnt2, N );
fenzi = ( cnt1 * N + cnt2 ) / d;
fenmu = N / d;
}
else {
fenzi = N;
if ( cnt1 == 0 )
fenzi = 0;
fenmu = 1;
}

if ( cnt1 == 0 && cnt2 == 0 && cnt3 == 0 )
flag1 = 0;
if ( flag1 )
printf ( "-" );
if ( ! flag2 ) {
printf ( "%lld/%lld\n", fenzi, fenmu );
continue;
}

N = ( LL ) ( pow ( 10, tot3 ) ) - 1;
N = N * ( LL ) ( pow ( 10, tot2 ) );
d = gcd ( cnt3, N );
LL newfenzi = cnt3 / d;
LL newfenmu = N / d;

if ( newfenmu == fenmu ) {
d = gcd ( fenzi + newfenzi, fenmu );
printf ( "%lld/%lld\n", ( fenzi + newfenzi ) / d, fenmu / d );
}
else {
d = gcd ( newfenmu, fenmu );
LL lcm = newfenmu * ( fenmu / d );
fenzi = fenzi * ( lcm / fenmu );
newfenzi = newfenzi * ( lcm / newfenmu );
d = gcd ( newfenzi + fenzi, lcm );
printf ( "%lld/%lld\n", ( fenzi + newfenzi ) / d, lcm / d );
}
}
return 0;
}


# T2：Slow Path Finding Algorithm

## 题目

Time limit: 6 seconds
Memory limit: 512 megabytes

Input

∑n ≤ 10 6 ,∑m ≤ 2 · 10 6 。
Output

Scoring

Example
spfa.in
3
1 0
1 1
1 1 a
4 6
1 2 i
1 3 a
1 4 k
2 3 i
2 4 o
3 4 i
spfa.out
0 a 1
1
-1
3 i 4
1 2 3 4

Note

## 题解

D P [ i ] [ j ] DP[i][j] 表示走到i号点为止，字母j出现的最多次数

1.我们不知道真正的起点到底是谁，只能知道目前的终点为i
2.如果用父亲更新儿子，就可以在拓扑排序找环的时候就一起处理了

D P [ v ] [ j ] = m a x ( D P [ v ] [ j ] , D P [ u ] [ j ] + ( c = = j ) ) DP[v][j]=max(DP[v][j],DP[u][j]+(c==j))

## 代码实现

#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <iostream>
using namespace std;
#define MAXN 100005
queue < int > q;
stack < int > path;
vector < vector < pair < int, int > > > G ( MAXN );
int T, n, m;
int d[MAXN];
int dp[MAXN][30], f[MAXN][30];

int main() {
scanf ( "%d", &T );
while ( T -- ) {
scanf ( "%d %d", &n, &m );
for ( int i = 1;i <= n;i ++ ) {
G[i].clear();
d[i] = 0;
for ( int j = 0;j < 26;j ++ )
dp[i][j] = f[i][j] = 0;
}
for ( int i = 1;i <= m;i ++ ) {
int u, v;char c;
scanf ( "%d %d %c", &u, &v, &c );
G[u].push_back( make_pair ( v, c - 'a' ) );
d[v] ++;
}
int tot = 0;
for ( int i = 1;i <= n;i ++ )
if ( ! d[i] ) {
q.push ( i );
tot ++;
}
while ( ! q.empty() ) {
int t = q.front();
q.pop();
for ( int i = 0;i < G[t].size();i ++ ) {
int v = G[t][i].first;
int c = G[t][i].second;
for ( int j = 0;j < 26;j ++ )
if ( dp[t][j] + ( c == j ) > dp[v][j] ) {
dp[v][j] = dp[t][j] + ( c == j );
f[v][j] = t;
}
d[v] --;
if ( ! d[v] ) {
q.push ( v );
tot ++;
}
}
}
if ( tot != n )
printf ( "-1\n" );
else {
int result = -1, str, idx;
for ( int i = 1;i <= n;i ++ )
for ( int j = 0;j < 26;j ++ )
if ( dp[i][j] > result ) {
result = dp[i][j];
str = j;
idx = i;
}
while ( idx != 0 ) {
path.push ( idx );
idx = f[idx][str];
}
printf ( "%d %c %d\n", result, str + 'a', path.size() );
while ( ! path.empty() ) {
printf ( "%d ", path.top() );
path.pop();
}
printf ( "\n" );
}
}
return 0;
}


# T3：切面包

## 题目

Time limit: 1 second
Memory limit: 512 megabytes

H 有 x 段连续的没有裂开的面包，则朋友的开心度为 x2

Input

1 x i q i (1 ≤ x i ≤ n, 0 ≤ q i ≤ 998244352)——表示小 H 加工了第 x i 段面包，加工后 p[x i] 变成了 q i
2 l i r i (1 ≤ l i ≤ r i ≤ n)——表示小 H 询问若切下 [l i ,r i ] 内的面包，朋友的期望开心度是多少
Output

Scoring

Example
divide.in
3 5
499122176 499122176 499122176
2 1 1
2 1 2
2 1 3
1 2 0
2 1 3
divide.out
499122177
249561089
748683266
1

Note

## 题解

1 + ∑ i = 1 n − 1 ( x i + x i + 1 − x i x i + 1 ) − ∑ i = 1 n x i = 1 + ∑ i = 2 n − 1 x i − ∑ i = 1 n − 1 x i x i + 1 1+\sum_{i=1}^{n-1}(x_i+x_{i+1}-x_ix_{i+1})-\sum_{i=1}^nx_i=1+\sum_{i=2}^{n-1}x_i-\sum_{i=1}^{n-1}x_ix_{i+1}

1 + ∑ 2 ≤ i < n ∑ 2 ≤ j < n x i x j + ∑ 1 ≤ i < n ∑ 1 ≤ j < n x i x i + 1 x j x j + 1 + 2 ∑ 2 ≤ i < n x i − 2 ∑ 1 ≤ i < n x i x i + 1 − 2 ∑ 2 ≤ i < n ∑ 1 ≤ j < n x i x j x j + 1 1+\sum_{2≤i<n}\sum_{2≤j<n}x_ix_j+\sum_{1≤i<n}\sum_{1≤j<n}x_ix_{i+1}x_jx_{j+1}+2\sum_{2≤i<n}x_i-2\sum_{1≤i<n}x_ix_{i+1}-2\sum_{2≤i<n}\sum_{1≤j<n}x_ix_jx_{j+1}

1 + ( ∑ i = 2 n − 1 p i ) 2 + 3 ∑ i = 2 n − 1 p i − ∑ i = 2 n − 1 p i 2 + ( ∑ i = 1 n − 1 p i p i + 1 ) 2 + 2 ∑ i = 1 n − 2 p i p i + 1 p i + 2 − 2 ∑ i = 2 n − 2 p i p i + 1 2 p i + 2 1+(\sum_{i=2}^{n-1}p_i)^2+3\sum_{i=2}^{n-1}p_i-\sum_{i=2}^{n-1}p_i^2+(\sum_{i=1}^{n-1}p_ip_{i+1})^2+2\sum_{i=1}^{n-2}p_ip_{i+1}p_{i+2}-2\sum_{i=2}^{n-2}p_ip_{i+1}^2p_{i+2}
− 5 ∑ i = 1 n − 1 p i p i + 1 + 2 ∑ i = 2 n − 1 p i 2 p i + 1 + 2 ∑ i = 1 n − 2 p i p i + 1 2 − ∑ i = 1 n − 1 p i 2 p i + 1 2 − 2 ( ∑ i = 2 n − 1 p i ) ( ∑ i = 1 n − 1 p i p i + 1 ) + 2 p 1 p 2 + 2 p n − 1 p n -5\sum_{i=1}^{n-1}p_ip_{i+1}+2\sum_{i=2}^{n-1}p_i^2p_{i+1}+2\sum_{i=1}^{n-2}p_ip_{i+1}^2-\sum_{i=1}^{n-1}p_i^2p_{i+1}^2-2(\sum_{i=2}^{n-1}p_i)(\sum_{i=1}^{n-1}p_ip_{i+1})+2p_1p_2 + 2p_{n-1}p_n

1 + ∑ i = 1 n − 1 ( x i + x i + 1 − x i x i + 1 ) − ∑ i = 1 n x i = 1 + ∑ i = 2 n − 1 x i − ∑ i = 1 n − 1 x i x i + 1 1+\sum_{i=1}^{n-1}(x_i+x_{i+1}-x_ix_{i+1})-\sum_{i=1}^nx_i=1+\sum_{i=2}^{n-1}x_i-\sum_{i=1}^{n-1}x_ix_{i+1}

p i ∗ p i = p i p_i*p_i=p_i 　　表示的意义：pi事件和pi事件同时发生的概率就是pi事件发生的概率
p i + p j ≠ p i ∗ p j p_i+p_j≠p_i*p_j 表示的意义：pi事件发生的概率和pj事件发生的概率并不等于pi和pj事件同时发生的概率

①1就不变，直接往下移，好了我们已经处理好了 1 6 \frac{1}{6}

+ ∑ 2 ≤ i < n ∑ 2 ≤ j < n x i x j +\sum_{2≤i<n}\sum_{2≤j<n}x_ix_j

+ ( ∑ i = 2 n − 1 p i ) 2 − ∑ i = 2 n − 1 p i 2 + ∑ i = 2 n − 1 p i +(\sum_{i=2}^{n-1}p_i)^2-\sum_{i=2}^{n-1}p_i^2+\sum_{i=2}^{n-1}p_i

+ ∑ 2 ≤ i < n ∑ 1 ≤ j < n x i x i + 1 x j x j + 1 +\sum_{2≤i<n}\sum_{1≤j<n}x_ix_{i+1}x_jx_{j+1}

( ∑ i = 1 n − 1 p i p i + 1 ) 2 + 2 ∑ i = 1 n − 2 p i p i + 1 p i + 2 − 2 ∑ i = 1 n − 2 p i p i + 1 2 p i + 2 − ∑ i = 1 n − 1 p i 2 p i + 1 2 + ∑ i = 1 n − 1 p i p i + 1 (\sum_{i=1}^{n-1}p_ip_{i+1})^2+2\sum_{i=1}^{n-2}p_ip_{i+1}p_{i+2}-2\sum_{i=1}^{n-2}p_ip_{i+1}^2p_{i+2}-\sum_{i=1}^{n-1}p_i^2p_{i+1}^2+\sum_{i=1}^{n-1}p_ip_{i+1}

+ 2 ∑ 2 ≤ i < n x i +2\sum_{2≤i<n}x_i

+ 2 ∑ i = 2 n − 1 p i +2\sum_{i=2}^{n-1}p_i

− 2 ∑ 1 ≤ i < n x i x i + 1 -2\sum_{1≤i<n}x_ix_{i+1}

− 2 ∑ i = 1 n − 1 p i p i + 1 -2\sum_{i=1}^{n-1}p_ip_{i+1}

− 2 ∑ 2 ≤ i < n ∑ 1 ≤ j < n x i x j x j + 1 -2\sum_{2≤i<n}\sum_{1≤j<n}x_ix_jx_{j+1}

− 2 ( ∑ i = 2 n − 1 p i ) ( ∑ i = 1 n − 1 p i p i + 1 ) − 4 ∑ i = 1 n − 1 p i p i + 1 + 2 ∑ i = 1 n − 1 p i 2 p i + 1 + 2 ∑ i = 1 n − 1 p i p i + 1 2 -2(\sum_{i=2}^{n-1}p_i)(\sum_{i=1}^{n-1}p_ip_{i+1})-4\sum_{i=1}^{n-1}p_ip_{i+1}+2\sum_{i=1}^{n-1}p_i^2p_{i+1}+2\sum_{i=1}^{n-1}p_ip_{i+1}^2

− 2 ( ∑ i = 2 n − 1 p i ) ( ∑ i = 1 n − 1 p i p i + 1 ) − 4 ∑ i = 1 n − 1 p i p i + 1 + 2 ∑ i = 2 n − 1 p i 2 p i + 1 + 2 ∑ i = 1 n − 2 p i p i + 1 2 -2(\sum_{i=2}^{n-1}p_i)(\sum_{i=1}^{n-1}p_ip_{i+1})-4\sum_{i=1}^{n-1}p_ip_{i+1}+2\sum_{i=2}^{n-1}p_i^2p_{i+1}+2\sum_{i=1}^{n-2}p_ip_{i+1}^2

+ 2 ∑ i = 1 n − 1 p i 2 p i + 1 , + 2 ∑ i = 2 n − 1 p i 2 p i + 1 +2\sum_{i=1}^{n-1}p_i^2p_{i+1},+2\sum_{i=2}^{n-1}p_i^2p_{i+1}

+ 2 ∑ i = 1 n − 1 p i 2 p i + 1 = + 2 ∑ i = 2 n − 1 p i 2 p i + 1 + 2 p 1 p 2 +2\sum_{i=1}^{n-1}p_i^2p_{i+1}=+2\sum_{i=2}^{n-1}p_i^2p_{i+1}+2p_1p_2

+ 2 ∑ i = 1 n − 1 p i p i + 1 2 , + 2 ∑ i = 1 n − 2 p i p i + 1 2 +2\sum_{i=1}^{n-1}p_ip_{i+1}^2,+2\sum_{i=1}^{n-2}p_ip_{i+1}^2

+ 2 ∑ i = 1 n − 1 p i p i + 1 2 = + 2 ∑ i = 1 n − 2 p i p i + 1 2 + 2 p n − 1 p n +2\sum_{i=1}^{n-1}p_ip_{i+1}^2=+2\sum_{i=1}^{n-2}p_ip_{i+1}^2+2p_{n-1}p_n

− 2 ( ∑ i = 2 n − 1 p i ) ( ∑ i = 1 n − 1 p i p i + 1 ) − 4 ∑ i = 1 n − 1 p i p i + 1 + 2 ∑ i = 2 n − 1 p i 2 p i + 1 + 2 ∑ i = 1 n − 2 p i p i + 1 2 + 2 p 1 p 2 + 2 p n − 1 p n -2(\sum_{i=2}^{n-1}p_i)(\sum_{i=1}^{n-1}p_ip_{i+1})-4\sum_{i=1}^{n-1}p_ip_{i+1}+2\sum_{i=2}^{n-1}p_i^2p_{i+1}+2\sum_{i=1}^{n-2}p_ip_{i+1}^2+2p_1p_2+2p_{n-1}p_n

## 代码实现

#include <cstdio>
#define mod 998244353
#define LL long long
#define MAXN 100005
struct node {
LL p, p2, pp, p2p, pp2, p2p2, ppp, pp2p;
node ( LL p = 0, LL p2 = 0, LL pp = 0, LL p2p = 0, LL pp2 = 0, LL p2p2 = 0, LL ppp = 0, LL pp2p = 0 ) :
p ( p ), p2 ( p2 ), pp ( pp ), p2p ( p2p ), pp2 ( pp2 ), p2p2 ( p2p2 ), ppp ( ppp ), pp2p ( pp2p ) {}
}tree[MAXN << 2];
int n, m;
LL p[MAXN];

node operator + ( const node &u, node &v ) {
return node ( ( u.p + v.p ) % mod, ( u.p2 + v.p2 ) % mod,
( u.pp + v.pp ) % mod, ( u.p2p + v.p2p ) % mod,
( u.pp2 + v.pp2 ) % mod, ( u.p2p2 + v.p2p2 ) % mod,
( u.ppp + v.ppp ) % mod, ( u.pp2p + v.pp2p ) % mod );
}

void count ( int num, int i ) {
tree[num].p = p[i] % mod;
tree[num].p2 = p[i] * p[i] % mod;
tree[num].pp = p[i] * p[i + 1] % mod;
tree[num].p2p = tree[num].p2 * p[i + 1] % mod;
tree[num].pp2 = tree[num].pp * p[i + 1] % mod;
tree[num].ppp = tree[num].pp * p[i + 2] % mod;
tree[num].pp2p = tree[num].pp2 * p[i + 2] % mod;
tree[num].p2p2 = tree[num].pp * tree[num].pp % mod;
}

void build ( int num, int l, int r ) {
if ( l == r ) {
count ( num, l );
return;
}
int mid = ( l + r ) >> 1;
build ( num << 1, l, mid );
build ( num << 1 | 1, mid + 1, r );
tree[num] = tree[num << 1] + tree[num << 1 | 1];
}

void update ( int num, int l, int r, int id ) {
if ( l == r ) {
count ( num, id );
return;
}
int mid = ( l + r ) >> 1;
if ( id <= mid )
update ( num << 1, l, mid, id );
else
update ( num << 1 | 1, mid + 1, r, id );
tree[num] = tree[num << 1] + tree[num << 1 | 1];
}

node range_sum ( int num, int l, int r, int L, int R ) {
if ( L <= l && r <= R )
return tree[num];
int mid = ( l + r ) >> 1;
node lsum( 0, 0, 0, 0, 0, 0, 0, 0 ), rsum( 0, 0, 0, 0, 0, 0, 0, 0 );
if ( L <= mid )
lsum = range_sum ( num << 1, l, mid, L, R );
if ( mid < R )
rsum = range_sum ( num << 1 | 1, mid + 1, r, L, R );
return lsum + rsum;
}

LL query ( int l, int r ) {
if ( l == r )
return ( 1 - p[l] + mod ) % mod;
node t = range_sum ( 1, 1, n, l, r );

t.p = ( ( t.p - p[r] - p[l] ) % mod + mod ) % mod;

t.p2 = ( ( t.p2 - p[r] * p[r] % mod - p[l] * p[l] % mod ) % mod + mod ) % mod;

t.p2p = ( ( t.p2p - p[l] * p[l] % mod * p[l + 1] % mod
- p[r] * p[r] % mod * p[r + 1] % mod ) % mod + mod ) % mod;

t.pp2 = ( ( t.pp2 - p[r - 1] * p[r] % mod * p[r] % mod
- p[r] * p[r + 1] % mod * p[r + 1] % mod ) % mod + mod ) % mod;

t.pp = ( ( t.pp - p[r] * p[r + 1] % mod ) % mod + mod ) % mod;

t.p2p2 = ( ( t.p2p2 - p[r] * p[r] % mod * p[r + 1] % mod * p[r + 1] % mod ) % mod + mod ) % mod;

t.ppp = ( ( t.ppp - p[r - 1] * p[r] % mod * p[r + 1] % mod
- p[r] * p[r + 1] % mod * p[r + 2] % mod ) % mod + mod ) % mod;

t.pp2p = ( ( t.pp2p - p[r - 1] * p[r] % mod * p[r] % mod * p[r + 1] % mod
- p[r] * p[r + 1] % mod * p[r + 1] % mod * p[r + 2] % mod ) % mod + mod ) % mod;

LL ans = ( ( 1 + t.p * t.p % mod + 3 * t.p % mod - t.p2 + t.pp * t.pp % mod
+ 2 * t.ppp % mod - 2 * t.pp2p % mod - 5 * t.pp % mod + 2 * t.p2p % mod
+ 2 * t.pp2 % mod - t.p2p2 - 2 * t.p * t.pp % mod
+ 2 * p[l] * p[l + 1] % mod + 2 * p[r - 1] * p[r] % mod ) % mod + mod ) % mod;
return ans;
}

int main() {
scanf ( "%d %d", &n, &m );
for ( int i = 1;i <= n;i ++ ) {
scanf ( "%lld", &p[i] );
p[i] = ( mod - p[i] ) % mod;
}
build ( 1, 1, n );
for ( int i = 1;i <= m;i ++ ) {
int opt;
scanf ( "%d", &opt );
if ( opt == 1 ) {
int x, q;
scanf ( "%d %d", &x, &q );
p[x] = ( mod - q ) % mod;
update( 1, 1, n, x );
if ( x > 1 )
update ( 1, 1, n, x - 1 );
if ( x > 2 )
update ( 1, 1, n, x - 2 );
}
else {
int l, r;
scanf ( "%d %d", &l, &r );
printf ( "%lld\n", query ( l, r ) % mod );
}
}
return 0;
}


• 1
点赞
• 0
评论
• 1
收藏
• 打赏
• 扫一扫，分享海报

11-07 91

10-28 85
07-21 537
05-15 9988
07-28 2212
11-10 56
08-10 422
05-14 698
03-12 2076
10-04 2628
08-09 1万+
©️2022 CSDN 皮肤主题：游动-白 设计师：我叫白小胖

ikrvxt

¥2 ¥4 ¥6 ¥10 ¥20

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。