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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Codeforces 1110 简要题解

發布時間:2025/3/14 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Codeforces 1110 简要题解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • A題
  • B題
  • C題
  • D題
  • E題
  • F題
  • G題

傳送門
眾所周知ldxoildxoildxoi這種菜雞選手是不會寫HHH題的,因此該篇博客只有AAA題至GGG題的題解,實在抱歉。

A題

傳送門
題意簡述:給出b,kb,kb,ka1,a2,...,aka_1,a_2,...,a_ka1?,a2?,...,ak?bk?1a1+bk?2a2+...+akb^{k-1}a_1+b^{k-2}a_2+...+a_kbk?1a1?+bk?2a2?+...+ak?的奇偶性。


思路:分bbb的奇偶性討論下就好。
代碼:

#include<bits/stdc++.h> #define ri register int #define fi first #define se second using namespace std; typedef long long ll; typedef pair<int,int> pii; const int mod=998244353; inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;} inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;} inline int mul(const int&a,const int&b){return (ll)a*b%mod;} inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)ret=mul(ret,a);return ret;} const int N=1e5+5; int b,k,a[N]; inline int read(){int ans=0;char ch=getchar();while(!isdigit(ch))ch=getchar();while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();return ans; } int main(){b=read(),k=read();int ans=0;bool f=b&1;if(!f){int x;while(k--)x=read();cout<<(x&1?"odd":"even");}else{for(ri i=k-1;~i;--i)ans+=read()&1;cout<<(ans&1?"odd":"even");}return 0; }

B題

傳送門
題意簡述:給出一條長為mmm的木板,上面有nnn個洞,你可以用不超過kkk段木板去補洞問覆蓋的最小長度。


思路:
如果k≥nk\ge nkn直接輸出nnn
否則先把所有的用一根木板補。
然后可以摳掉中間k?1k-1k?1段,于是我們把所有連續的兩個洞的距離放進堆里取前k?1k-1k?1大減掉即可。
代碼:

#include<bits/stdc++.h> #define ri register int #define fi first #define se second using namespace std; typedef long long ll; typedef pair<int,int> pii; const int mod=998244353; inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;} inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;} inline int mul(const int&a,const int&b){return (ll)a*b%mod;} inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)ret=mul(ret,a);return ret;} const int N=1e5+5; int n,m,k,a[N]; inline int read(){int ans=0;char ch=getchar();while(!isdigit(ch))ch=getchar();while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();return ans; } int main(){n=read(),m=read(),k=read();priority_queue<int>q;for(ri i=1;i<=n;++i)a[i]=read();sort(a+1,a+n+1);for(ri i=2;i<=n;++i)q.push(a[i]-a[i-1]-1);int delta=a[n]-a[1]+1;for(ri i=1;i<k;++i)delta-=q.top(),q.pop();cout<<delta;return 0; }

C題

傳送門
題意簡述:nnn次詢問(n≤2000n\le2000n2000),每次給一個a(2≤a≤225?1)a(2\le a\le2^{25}-1)a(2a225?1),問對于所有滿足0&lt;b&lt;a0&lt;b&lt;a0<b<abbbgcd(a&amp;b,agcd(a\&amp;b,agcd(a&b,a^b)b)b)的最大值是多少。


思路:

  • 打表
    打表代碼:
  • #include<bits/stdc++.h> using namespace std; int q,a,ans1[55]={0,2,3,4,7,8,15,16,31,32,63,64,127,128,255,256,511,512,1023,1024,2047,2048,4095,4096,8191,8192,16383,16384,32767,32768,65535,65536,131071,131072,262143,262144,524287,524288,1048575,1048576,2097151,2097152,4194303,4194304,8388607,8388608,16777215,16777216,33554431,33554432,67108863}; int ans2[55]={0,3,1,7,1,15,5,31,1,63,21,127,1,255,85,511,73,1023,341,2047,89,4095,1365,8191,1,16383,5461,32767,4681,65535,21845,131071,1,262143,87381,524287,1,1048575,349525,2097151,299593,4194303,1398101,8388607,178481,16777215,5592405,33554431,1082401,67108863,22369621}; inline int read(){int ans=0;char ch=getchar();while(!isdigit(ch))ch=getchar();while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();return ans; } int main(){q=read();while(q--) {a=read();int loc=upper_bound(ans1+1,ans1+51,a)-ans1;cout<<ans2[loc-1]<<endl;}return 0; }
  • 考慮到分aaa的情況討論
  • a?=2k?1a\not=2^k-1a??=2k?1那么取b=(2k?1)ab=(2^k-1)^ab=(2k?1)a即可,答案為2k?12^k-12k?1
  • a=2k?1a=2^k-1a=2k?1,那么直接枚舉其最大質因子,如果沒有就輸出111
  • 正解代碼:

    #include<bits/stdc++.h> #define ri register int #define fi first #define se second using namespace std; typedef long long ll; typedef pair<int,int> pii; const int mod=998244353; inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;} inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;} inline int mul(const int&a,const int&b){return (ll)a*b%mod;} inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)ret=mul(ret,a);return ret;} const int N=1e5+5; inline int read(){int ans=0;char ch=getchar();while(!isdigit(ch))ch=getchar();while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();return ans; } inline int lowbit(const int&x){return x&-x;} inline void solve1(const int&x){int up=1;while(up<=x)up<<=1;cout<<up-1<<'\n'; } inline void solve2(const int&x){for(ri i=2;i*i<=x;++i)if(x%i==0){cout<<x/i<<'\n';return;}puts("1"); } int main(){for(ri x,tt=read();tt;--tt){x=read();if(lowbit(x+1)!=x+1)solve1(x);else solve2(x);}return 0; }

    D題

    傳送門
    題意簡述:給nnn張大小不超過mmm的紙牌(n,m≤1000000)(n,m\le1000000)(n,m1000000)
    現在允許把滿足任意一種條件的三張牌分為一組:

  • 三張牌為連續自然數
  • 三張牌相同
  • 問分出來的最多的組數。


    思路:
    比賽的時候想了半天貪心發現是錯的?手動滑稽233
    然后就涼了。
    考慮dpdpdp
    對于連續的三個數x,x+1,x+2x,x+1,x+2x,x+1,x+2,如果我們分成三次(x,x+1,x+2)(x,x+1,x+2)(x,x+1,x+2)消耗的牌和分成(x,x,x),(x+1,x+1,x+1),(x+2,x+2,x+2)(x,x,x),(x+1,x+1,x+1),(x+2,x+2,x+2)(x,x,x),(x+1,x+1,x+1),(x+2,x+2,x+2)是等價的。
    于是對于連續的三張牌最多只用分兩次(x,x+1,x+2)(x,x+1,x+2)(x,x+1,x+2)
    于是我們定義狀態fi,t1,t2f_{i,t1,t2}fi,t1,t2?表示對于值為1?i1~i1?i的牌,我們分t1t1t1(i?1,i,i+1)(i-1,i,i+1)(i?1,i,i+1),分t2t2t2(i,i+1,i+2)(i,i+1,i+2)(i,i+1,i+2),然后枚舉fi+1,t2,t3f_{i+1,t2,t3}fi+1,t2,t3?轉移一下就行了,注意轉移的時候如果值為i+1i+1i+1的牌有剩的需要全部分成(i+1,i+1,i+1)(i+1,i+1,i+1)(i+1,i+1,i+1)
    代碼:

    #include<bits/stdc++.h> #define ri register int using namespace std; inline int read(){int ans=0;char ch=getchar();while(!isdigit(ch))ch=getchar();while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();return ans; } const int N=1e6+5; int f[N][3][3],a[N],n,m; int main(){n=read(),m=read();for(ri i=1;i<=n;++i)++a[read()];memset(f,-1,sizeof(f));f[0][0][0]=0;for(ri i=0;i<m+2;++i){for(ri t1=0;t1<=2;++t1){for(ri t2=0;t2<=2;++t2){if(~f[i][t1][t2]){for(ri t3=0;t3<=2;++t3){if(t1+t2+t3>a[i+1])continue;f[i+1][t2][t3]=max(f[i+1][t2][t3],f[i][t1][t2]+t3+(a[i+1]-t1-t2-t3)/3);}}}}}cout<<f[m+2][0][0];return 0; }

    E題

    傳送門
    題意簡述:給出兩個數列ana_nan?bn(n≤100000)b_n(n\le100000)bn?(n100000),可以對ai(2≤i≤n?1)a_i(2\le i\le n-1)ai?(2in?1)進行如下操作:ai=ai?1+ai+1?aia_i=a_{i-1}+a_{i+1}-a_{i}ai?=ai?1?+ai+1??ai?
    問能否通過若干次操作使得a,ba,ba,b完全一樣。


    思路:
    定義ci=ai?ai?1(i≤2),c1=a1c_i=a_i-a_{i-1}(i\le2),c_1=a_1ci?=ai??ai?1?(i2),c1?=a1?
    cccaaa的差分數組。
    發現每次操作就是交換cic_ici?ci+1c_{i+1}ci+1?
    于是把兩個數列的差分數列排序看是否一樣即可。
    注意特判兩個數的情況,這個時候并不能移動
    代碼:

    #include<bits/stdc++.h> #define ri register int #define fi first #define se second using namespace std; typedef long long ll; typedef pair<int,int> pii; const int mod=998244353; inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;} inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;} inline int mul(const int&a,const int&b){return (ll)a*b%mod;} inline int ksm(int a,int p){int ret=1;for(;p;p>>=1,a=mul(a,a))if(p&1)ret=mul(ret,a);return ret;} const int N=1e6+5; inline int read(){int ans=0;char ch=getchar();while(!isdigit(ch))ch=getchar();while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();return ans; } int n,m,a[N],b[N],c[N],d[N]; int main(){n=read();for(ri i=1;i<=n;++i)a[i]=read();for(ri i=1;i<=n;++i)c[i]=read();if(a[1]!=c[1]||a[n]!=c[n])puts("No"),exit(0);for(ri i=1;i<=n;++i)b[i]=a[i]-a[i-1],d[i]=c[i]-c[i-1];sort(b+1,b+n+1),sort(d+1,d+n+1);bool f=1;for(ri i=1;i<=n;++i)if(b[i]^d[i])f=0;if(f)puts("Yes");else puts("No");return 0; }

    F題

    傳送門
    題意簡述:給一棵nnn個點的帶邊權樹,有qqq次詢問(n,q≤500000)(n,q\le500000)(n,q500000),每次問你在所有dfsdfsdfs序在[l,r][l,r][l,r]之間的葉子結點跟xxx的最短距離。


    思路:
    考慮離線處理詢問,把所有詢問按照xxx歸類,于是只需動態維護在dfsdfsdfs到某個節點的時候知道dfsdfsdfs序在一段區間的葉子到當前點的距離最小值。
    我們先按照題目中說的順序遍歷處理出dfsdfsdfs序(其實就是用vectorvectorvector存邊)以及每個點到根的distdistdist,然后把葉子結點的distdistdist放入線段樹里,這樣就處理出了所有點到根節點的答案,然后考慮一個點向兒子節點移動的時候所有葉子結點到自己距離的變化,即兒子的子樹里的葉子整體減掉當前邊邊權,其余的葉子加上當前邊邊權即可。
    代碼:

    #include<bits/stdc++.h> #define ri register int #define fi first #define se second using namespace std; inline int read(){int ans=0;char ch=getchar();while(!isdigit(ch))ch=getchar();while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();return ans; } typedef pair<int,int> pii; typedef long long ll; const int N=5e5+5; int n,m,fa[N],in[N],out[N],top=0,tot=0,q[N]; ll dis[N],ans[N]; vector<pii>e[N]; struct Node{int l,r,id;}; vector<Node>qry[N]; namespace SGT{#define lc (p<<1)#define rc (p<<1|1)#define mid (l+r>>1)ll mn[N<<2],add[N<<2];inline void pushup(int p){mn[p]=min(mn[lc],mn[rc]);}inline void pushnow(int p,ll v){mn[p]+=v,add[p]+=v;}inline void pushdown(int p){if(add[p])pushnow(lc,add[p]),pushnow(rc,add[p]),add[p]=0;}inline void build(int p,int l,int r){add[p]=0;if(l==r){mn[p]=dis[q[l]];return;}build(lc,l,mid),build(rc,mid+1,r),pushup(p);}inline ll query(int p,int l,int r,int ql,int qr){if(ql<=l&&r<=qr)return mn[p];pushdown(p);if(qr<=mid)return query(lc,l,mid,ql,qr);if(ql>mid)return query(rc,mid+1,r,ql,qr);return min(query(lc,l,mid,ql,mid),query(rc,mid+1,r,mid+1,qr));}inline void update(int p,int l,int r,int ql,int qr,ll v){if(ql>r||qr<l)return;if(ql<=l&&r<=qr)return pushnow(p,v);pushdown(p);if(qr<=mid)update(lc,l,mid,ql,qr,v);else if(ql>mid)update(rc,mid+1,r,ql,qr,v);else update(lc,l,mid,ql,mid,v),update(rc,mid+1,r,mid+1,qr,v);pushup(p);} } inline int findl(const int&x){return lower_bound(q+1,q+top+1,x)-q;} inline int findr(const int&x){int ret=lower_bound(q+1,q+top+1,x)-q;return q[ret]>x?ret-1:ret;} void dfs1(int p){in[p]=++tot;for(ri i=0,v;i<e[p].size();++i)dis[v=e[p][i].fi]=dis[p]+e[p][i].se,dfs1(v);out[p]=tot;if(!e[p].size())q[++top]=p; } void dfs2(int p){for(ri i=0,l,r;i<qry[p].size();++i)ans[qry[p][i].id]=SGT::query(1,1,top,qry[p][i].l,qry[p][i].r);for(ri i=0,l,r,v,w;i<e[p].size();++i){v=e[p][i].fi,l=findl(in[v]),r=findr(out[v]),w=e[p][i].se;SGT::update(1,1,top,l,r,-w),SGT::update(1,1,top,1,l-1,w),SGT::update(1,1,top,r+1,top,w);dfs2(v);SGT::update(1,1,top,l,r,w),SGT::update(1,1,top,1,l-1,-w),SGT::update(1,1,top,r+1,top,-w);} } int main(){n=read(),m=read();for(ri i=2;i<=n;++i)fa[i]=read(),e[fa[i]].push_back(pii(i,read()));dfs1(1),SGT::build(1,1,top);for(ri i=1;i<=top;++i)q[i]=in[q[i]];for(ri i=1,x,l,r;i<=m;++i){x=read(),l=findl(read()),r=findr(read());qry[x].push_back((Node){l,r,i});}dfs2(1);for(ri i=1;i<=m;++i)cout<<ans[i]<<'\n';return 0; }

    G題

    傳送門
    題意簡述:給出一棵樹,上面有的點是白色的有的沒有涂色,現在兩個人輪流涂色,先手涂白色,后手涂黑色,當某一方涂出了一條長度為333的路徑時宣告勝利,如果全部涂完都沒有滿足條件即是和局,問雙方都采取最優策略的最終結果。


    思路:顯然后手贏是不可能的 ,這輩子都不可能的
    那么只需判斷先手能不能贏了。
    這個初始局的白色很煩人,因此我們改改條件,對于一個初始為白色的點AAA,把它拓展成444個點:

    然后其余的邊還是連向AAA點,這個時候我們假如涂AAA后手一定會涂BBB,就回到了跟初始是白色等價的情況。

    于是我們成功把問題轉化成為了初始沒有涂色的情況。
    現在考慮先手勝利的條件:
    第一種:

    第二種:


    第三種:

    這種注意,方法是放最靠中間的兩個:

    這樣子先手必勝。
    注意這種情況中間的直鏈的長度必須要是奇數才行(大家可以手玩感受一下)
    代碼:

    #include<bits/stdc++.h> #define ri register int using namespace std; inline int read(){int ans=0;char ch=getchar();while(!isdigit(ch))ch=getchar();while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();return ans; } const int N=5e5+5; int n=0,du[N*4],cnt[2]; vector<int>e[N*4]; char s[N]; void dfs(int p,int fa,int dist){if(e[p].size()>=3)++cnt[dist];for(ri i=0,v;i<e[p].size();++i)if((v=e[p][i])^fa)dfs(v,p,dist^1); } inline bool solve(const int&p){if(du[p]>=4)return 1;if(du[p]<=2)return 0;int cnt=0;for(ri i=0;i<e[p].size();++i)if(du[e[p][i]]>1)++cnt;return cnt>=2; } inline void add(int u,int v){e[u].push_back(v),++du[u];e[v].push_back(u),++du[v]; } int main(){for(ri tt=read(),tot;tt;--tt){for(ri i=1;i<=n;++i)e[i].clear(),du[i]=0;n=read(),cnt[0]=cnt[1]=0;for(ri i=1,u,v;i<n;++i)u=read(),v=read(),add(u,v);scanf("%s",s+1),tot=n;for(ri i=1;i<=n;++i)if(s[i]=='W'){++tot;add(i,tot),add(tot,tot+1),add(tot,tot+2),tot+=2;}n=tot,dfs(1,0,0);if(cnt[0]>1||cnt[1]>1){puts("White");continue;}bool flag=0;for(ri i=1;i<=n;++i)flag|=solve(i);puts(flag?"White":"Draw");}return 0; }

    轉載于:https://www.cnblogs.com/ldxcaicai/p/10367704.html

    總結

    以上是生活随笔為你收集整理的Codeforces 1110 简要题解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。