日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[AtCoder Regular Contest 123] 题解

發(fā)布時間:2023/12/3 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [AtCoder Regular Contest 123] 题解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • A - Arithmetic Sequence
  • B - Increasing Triples
  • C - 1, 2, 3 - Decomposition
  • D - Inc, Dec - Decomposition
  • E - Training
  • F - Insert Addition

ARC123

A - Arithmetic Sequence

大討論

只能+1+1+1,先固定中間的數(shù),看兩邊加誰,如果都是加負數(shù)說明是中間的數(shù)需要加

#include <cstdio> #include <iostream> using namespace std; #define int long long int x, y, z;int Fabs( int x ) {return x < 0 ? -x : x; }signed main() {scanf( "%lld %lld %lld", &x, &y, &z );if( x > z ) swap( x, z );int d1 = y - x, d2 = z - y;int x1 = y - d2, z1 = y + d1;if( x1 >= x ) printf( "%lld\n", x1 - x );else if( z1 >= z ) printf( "%lld\n", z1 - z );else if( ( z - x ) & 1 ) printf( "%lld\n", x + ( z - x ) / 2 - y + 2 );else printf( "%lld\n", x + ( z - x ) / 2 - y );return 0; }

B - Increasing Triples

排序一邊,貪心的有盡可能讓小小小,大大大配對出現(xiàn),雙指針掃即可

#include <cstdio> #include <algorithm> using namespace std; #define maxn 100005 int A[maxn], B[maxn], C[maxn]; int n;int main() {scanf( "%d", &n );for( int i = 1;i <= n;i ++ )scanf( "%d", &A[i] );for( int i = 1;i <= n;i ++ )scanf( "%d", &B[i] );for( int i = 1;i <= n;i ++ )scanf( "%d", &C[i] );sort( A + 1, A + n + 1 );sort( B + 1, B + n + 1 );sort( C + 1, C + n + 1 );int ipB = 1, ipC = 1, ans = 0;for( int i = 1;i <= n;i ++ ) {while( ipB <= n && B[ipB] <= A[i] ) ipB ++;while( ipC <= n && C[ipC] <= B[ipB] ) ipC ++;if( ipB > n || ipC > n ) break;else ans ++, ipB ++, ipC ++;}printf( "%d\n", ans );return 0; }

C - 1, 2, 3 - Decomposition

結(jié)論:任何一個數(shù)最多不會由超過五個的123類數(shù)組成

暴力算每各位check,1/2/3/4/5依次是否可以

#include <map> #include <cstdio> using namespace std; #define int long long map < int, int > mp; int T, n;int solve( int n ) {if( ! n ) return 0;if( mp[n] ) return mp[n];int s = n / 10, r = n % 10;if( 1 <= r && r <= 3 && solve( s ) <= 1 ) return mp[n] = 1;if( 2 <= r && r <= 6 && solve( s ) <= 2 ) return mp[n] = 2;if( 3 <= r && r <= 9 && solve( s ) <= 3 ) return mp[n] = 3;if( 4 <= r && r <= 9 && solve( s ) <= 4 ) return mp[n] = 4;if( 0 <= r && r <= 2 && solve( s - 1 ) <= 4 ) return mp[n] = 4;return mp[n] = 5; }signed main() {scanf( "%lld", &T );while( T -- ) {scanf( "%lld", &n );printf( "%lld\n", solve( n ) ); }return 0; }

D - Inc, Dec - Decomposition

顯然的定理:對于操作iiiBi=Bi?1/Ci=Ci?1B_i=B_{i-1}/C_i=C_{i-1}Bi?=Bi?1?/Ci?=Ci?1?二者中至少有一個是不變的

所以,一旦確定了B1B_1B1?,兩個序列都被確定下來,答案也就確定了

反轉(zhuǎn)CCC,重新定義為Ai=Bi?CiA_i=B_i-C_iAi?=Bi??Ci?,那么B,CB,CB,C序列的要求都變成了單調(diào)不下降

最后的答案反正是帶絕對值的,這樣的反轉(zhuǎn)并不影響最后答案的統(tǒng)計,還是∑i=1n∣Bi∣+∣Ci∣\sum_{i=1}^n|B_i|+|C_i|i=1n?Bi?+Ci?

Ai+1>AiA_{i+1}>A_iAi+1?>Ai?,原問題的解決方案肯定是增加BBB,若Ai+1<AiA_{i+1}<A_iAi+1?<Ai?,原問題的解決方案肯定是減少CCC

原則上是沒有變化的,但是改變CCC后,全都變成了增加B/CB/CB/C,操作可以表示為

  • Bi+1=Bi+max?(Ai+1?Ai,0)B_{i+1}=B_{i}+\max(A_{i+1}-A_i,0)Bi+1?=Bi?+max(Ai+1??Ai?,0)
  • Ci+1=Ci+max?(Ai?Ai+1,0)C_{i+1}=C_i+\max(A_i-A_{i+1},0)Ci+1?=Ci?+max(Ai??Ai+1?,0)

對于確定了B1B_1B1?后的序列,每個Bi,CiB_i,C_iBi?,Ci?都是∣B1?k∣|B_1-k|B1??k的形式,一共有2n2n2nkkk,答案顯然是BiB_iBi?kkk的中位數(shù)時最小

#include <cstdio> #include <vector> #include <algorithm> using namespace std; #define int long long #define maxn 200005 vector < int > ans; int n; int A[maxn];int Fabs( int x ) {return x < 0 ? -x : x; }signed main() {scanf( "%lld", &n );for( int i = 1;i <= n;i ++ )scanf( "%lld", &A[i] );int B = A[1], C = 0;ans.push_back( B ), ans.push_back( C );for( int i = 1;i < n;i ++ ) {int x = A[i + 1] - A[i];if( x >= 0 ) B += x;else C -= x;ans.push_back( B );ans.push_back( C );}sort( ans.begin(), ans.end() );int ret = 0;for( int i = 0;i < ans.size();i ++ )ret += Fabs( ans[i] - ans[n] );printf( "%lld\n", ret );return 0; }

E - Training

題目轉(zhuǎn)錄翻譯一下就是求∑i=1n[AX+?iBX?=AY+?iBY?]\sum_{i=1}^n\bigg[A_X+\lfloor\frac{i}{B_X}\rfloor=A_Y+\lfloor\frac{i}{B_Y}\rfloor\bigg]i=1n?[AX?+?BX?i??=AY?+?BY?i??]

定義f(x)=AX+xBX,g(x)=AY+xBY,F(x)=?f(x)?,G(x)=?g(x)?f(x)=A_X+\frac{x}{B_X},g(x)=A_Y+\frac{x}{B_Y},F(x)=\lfloor f(x)\rfloor,G(x)=\lfloor g(x)\rfloorf(x)=AX?+BX?x?,g(x)=AY?+BY?x?,F(x)=?f(x)?,G(x)=?g(x)?

問題轉(zhuǎn)化為求∑i=1n[F(i)=G(i)]\sum_{i=1}^n\bigg[F(i)=G(i)\bigg]i=1n?[F(i)=G(i)]

  • f(x)<g(x)?1?F(x)<G(x)f(x)<g(x)-1\Rightarrow F(x)<G(x)f(x)<g(x)?1?F(x)<G(x)

  • g(x)?1≤f(x)≤g(x)?F(x)={G(x)?1,G(x)}g(x)-1\le f(x)\le g(x)\Rightarrow F(x)=\bigg\{G(x)-1,G(x)\bigg\}g(x)?1f(x)g(x)?F(x)={G(x)?1,G(x)}

    • g(x)?1≤f(x)g(x)-1\le f(x)g(x)?1f(x)

      AY+xBY?1≤AX+xBX?AYBYBX+xBX?BXBY≤AXBYBX+xBYA_Y+\frac{x}{B_Y}-1\le A_X+\frac{x}{B_X}\Leftrightarrow A_YB_YB_X+xB_X-B_XB_Y\le A_XB_YB_X+xB_YAY?+BY?x??1AX?+BX?x??AY?BY?BX?+xBX??BX?BY?AX?BY?BX?+xBY?

      ?(AY?AX?1)BXBY≤x(BY?BX)?(AY?AX?1)BXBYBY?BX≤x\Leftrightarrow (A_Y-A_X-1)B_XB_Y\le x(B_Y-B_X)\Leftrightarrow \frac{(A_Y-A_X-1)B_XB_Y}{B_Y-B_X}\le x?(AY??AX??1)BX?BY?x(BY??BX?)?BY??BX?(AY??AX??1)BX?BY??x

    • f(x)≤g(x)f(x)\le g(x)f(x)g(x)

      (AY?AX)BXBYBY?BX≥x\frac{(A_Y-A_X)B_XB_Y}{B_Y-B_X}\ge xBY??BX?(AY??AX?)BX?BY??x

  • g(x)<f(x)≤g(x)+1?F(x)={G(x),G(x)+1}g(x)<f(x)\le g(x)+1\Rightarrow F(x)=\bigg\{G(x),G(x)+1\bigg\}g(x)<f(x)g(x)+1?F(x)={G(x),G(x)+1}

    • g(x)<f(x)g(x)<f(x)g(x)<f(x)

      (AY?AX)BXBYBY?BX<x\frac{(A_Y-A_X)B_XB_Y}{B_Y-B_X}< xBY??BX?(AY??AX?)BX?BY??<x

    • f(x)<g(x)+1f(x)<g(x)+1f(x)<g(x)+1

      (AY?AX+1)BXBYBY?BX>x\frac{(A_Y-A_X+1)B_XB_Y}{B_Y-B_X}> xBY??BX?(AY??AX?+1)BX?BY??>x

  • g(x)+1<f(x)?F(x)>G(x)g(x)+1<f(x)\Rightarrow F(x)>G(x)g(x)+1<f(x)?F(x)>G(x)

只有兩種情況才可能出現(xiàn)F(x)=G(x)F(x)=G(x)F(x)=G(x),并且可以數(shù)學(xué)化的解出f(x)f(x)f(x)的范圍

在已知范圍[l,r][l,r][l,r]內(nèi),可以巧妙轉(zhuǎn)化,∑i=lr[F(i)=G(i)]?(r?l+1)?∣∑x=lrAX+?xBX??∑x=lrAY+?xBY?∣\sum_{i=l}^r\bigg[F(i)=G(i)\bigg]\Leftrightarrow (r-l+1)-\bigg|\sum_{x=l}^rA_X+\lfloor\frac{x}{B_X}\rfloor-\sum_{x=l}^{r}A_Y+\lfloor\frac{x}{B_Y}\rfloor\bigg|i=lr?[F(i)=G(i)]?(r?l+1)??x=lr?AX?+?BX?x???x=lr?AY?+?BY?x???

差分地計算∑x=lrAX+?xBX?\sum_{x=l}^rA_X+\lfloor\frac{x}{B_X}\rfloorx=lr?AX?+?BX?x??

∑x=1na+?xb?=b?(a+a+?nb??1)??xb?2+(n??nb??b+1)?(a+?xb?)\sum_{x=1}^na+\lfloor\frac{x}{b}\rfloor=b*\frac{(a+a+\lfloor\frac{n}{b}\rfloor-1)*\lfloor\frac{x}{b}\rfloor}{2}+(n-\lfloor\frac{n}{b}\rfloor*b+1)*(a+\lfloor\frac{x}{b}\rfloor)x=1n?a+?bx??=b?2(a+a+?bn???1)??bx???+(n??bn???b+1)?(a+?bx??)

#include <cmath> #include <cstdio> #include <iostream> using namespace std; #define int long long #define eps 1e-8int calc( int a, int b, int n ) {int t = ( n + 1 ) / b;return ( a * 2 + ( t - 1 ) ) * t * b / 2 + ( a + t ) * ( n - t * b + 1 ); }signed main() {int T, n, AX, AY, BX, BY;scanf( "%lld", &T );long double L, R; int l, r, ans, cnt;while( T -- ) {scanf( "%lld %lld %lld %lld %lld", &n, &AX, &BX, &AY, &BY );if( BX == BY ) {if( AX == AY ) printf( "%lld\n", n );else printf( "0\n" );continue;}if( BX > BY ) swap( AX, AY ), swap( BX, BY );ans = 0;//g(x)-1<=f(x)<=g(x)L = 1.0 * ( AY - AX - 1 ) * BX * BY / ( BY - BX ) + eps;R = ( AY - AX ) * 1.0 * BX * BY / ( BY - BX );if( L < 1 ) l = 1;else l = ceil( L );if( R > n ) r = n;else r = floor( R );r = max( r, l - 1 );cnt = calc( AY, BY, r ) - calc( AY, BY, l - 1 ) - calc( AX, BX, r ) + calc( AX, BX, l - 1 );ans += r - l + 1 - cnt;//g(x)<f(x)<g(x)+1L = R + eps;R = ( AY - AX + 1 ) * 1.0 * BX * BY / ( BY - BX ) - eps;if( L < 1 ) l = 1;else l = ceil( L );if( R > n ) r = n;else r = floor( R );r = max( r, l - 1 );cnt = calc( AX, BX, r ) - calc( AX, BX, l - 1 ) - calc( AY, BY, r ) + calc( AY, BY, l - 1 );ans += r - l + 1 - cnt;printf( "%lld\n", ans );} return 0; }

F - Insert Addition

數(shù)列的生成類比斯坦納樹

因為a,ba,ba,b的范圍,迭代次數(shù)永遠小于生成數(shù)的大小,因此考慮充分迭代多次后保留≤n\le nn的數(shù)

如果(x1,y1),(x2,y2)(x_1,y_1),(x_2,y_2)(x1?,y1?),(x2?,y2?)在系數(shù)數(shù)列中相鄰,則有x1y2?x2y1=1x_1y_2-x_2y_1=1x1?y2??x2?y1?=1

并且只要坐標(biāo)都>0>0>0,那么總有一個時刻在系數(shù)數(shù)列中有且僅出現(xiàn)一次

這是個歐幾里得形式的式子,當(dāng)且僅當(dāng)(a,b)=1(a,b)=1(a,b)=1才有解

把數(shù)列當(dāng)成斯坦納樹跑成線段樹,(i,j)←(i?1,j?1)+(i?1,j+1)(i,j)\leftarrow (i-1,j-1)+(i-1,j+1)(i,j)(i?1,j?1)+(i?1,j+1)

gcd(a,b)=1?i?a+b?j≤ngcd(a,b)=1\Rightarrow i*a+b*j\le ngcd(a,b)=1?i?a+b?jn,就是莫比烏斯反演了,暴力枚舉iii暴力算

#include <cstdio> #define int long long #define maxn 300005 int mu[maxn], prime[maxn]; bool vis[maxn]; int a, b, n, l, r;void init() {int cnt = 0;mu[1] = 1;for( int i = 2;i <= n;i ++ ) {if( ! vis[i] ) prime[++ cnt] = i, mu[i] = -1;for( int j = 1;j <= cnt && i * prime[j] <= n;j ++ ) {vis[i * prime[j]] = 1;if( i % prime[j] == 0 ) break;else mu[i * prime[j]] = -mu[i];}} }void print( int x ) {if( l > r || x > n ) return;else if( l == 1 ) printf( "%lld ", x ), r --;else l --, r --; }int calc( int x, int y ) {int cnt = 0;for( int i = 1;x + y <= n / i;i ++ ) {if( ! mu[i] ) continue;for( int j = 1;x * j + y <= n / i;j ++ )cnt += mu[i] * ( n / i - x * j ) / y;}return cnt; }void print_all( int x, int y ) {if( x + y > n ) return;print_all( x, x + y );print( x + y );print_all( x + y, y ); }void dfs( int x, int y ) {int cnt = calc( x, y );if( l > r || ! cnt ) return;if( l > cnt ) {l -= cnt, r -= cnt;return;}if( l == 1 && cnt <= r ) {print_all( x, y );return;}dfs( x, x + y );print( x + y );dfs( x + y, y ); }signed main() {scanf( "%lld %lld %lld %lld %lld", &a, &b, &n, &l, &r );init();print( a ), dfs( a, b ), print( b );return 0; }

總結(jié)

以上是生活随笔為你收集整理的[AtCoder Regular Contest 123] 题解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。