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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

编程问答

CCPC-Wannafly Comet OJ 夏季欢乐赛(2019)

發(fā)布時(shí)間:2023/12/9 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CCPC-Wannafly Comet OJ 夏季欢乐赛(2019) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

感覺(jué)自己代碼能力好弱啊


T1 完全k叉樹

傳送門


Solution

首先特判一下K=1K=1K=1
然后處理出最大滿KKK叉樹,設(shè)這棵樹的深度為rankrankrank,根節(jié)點(diǎn)的深度為000,這個(gè)時(shí)候的答案,就是2?rank2*rank2?rank
如果還有剩下的節(jié)點(diǎn),顯然如果答案可以擴(kuò)大為2?rank+12*rank+12?rank+1
現(xiàn)在已經(jīng)考慮了深度小于等于rankrankrank的點(diǎn)互相匹配 and 深度為rank+1rank+1rank+1與深度小于等于rankrankrank的點(diǎn)配對(duì)的情況。
還有一種情況就是深度為rank+1rank+1rank+1的點(diǎn)相配對(duì),如果要使答案變大,則匹配的兩個(gè)點(diǎn)的lcalcalca必須是根節(jié)點(diǎn)(太好證了,請(qǐng)自行證明),處理出根節(jié)點(diǎn)的最左邊兒子在rank+1rank+1rank+1層需要多少個(gè)節(jié)點(diǎn)才能填滿,與剩下的節(jié)點(diǎn)判斷一下大小就好了。

#include<iostream> using namespace std; typedef long long ll; ll getSize(ll K,ll rk){ll ret = 1;ll cur = 1;for(int i=1;i<=rk;i++){cur *= K;ret += cur;}return cur; } void solve(){ll K,N;cin>>K>>N;if(K==1){cout<<N-1<<endl;return;}ll cur = 1;ll rank = 0;ll tmp = N-1;while(tmp >= cur * K){rank++;tmp -= cur * K;cur *= K;}if(rank==0){if(N==2){cout<<1<<endl;return;}else{cout<<2<<endl;return;}}ll ans = (rank<<1);if(tmp == 0){cout<<ans<<endl;return;}ans = max(rank*2+1,ans);ll pre = tmp / K;if(tmp % K)pre++;ll ned = getSize(K,rank-1);if(pre > ned){ans = max(rank*2+2,ans);}cout<<ans<<endl;} int main(){ios::sync_with_stdio(0);int T;cin>>T;while(T--){solve();}return 0; }

T2 距離產(chǎn)生美

傳送門


Solution

發(fā)現(xiàn)最大可以把數(shù)字修改成101810^{18}1018KKK最大才10910^9109
也就是說(shuō),修改過(guò)一個(gè)數(shù)之后,這個(gè)數(shù)的前后兩個(gè)數(shù)與當(dāng)前這個(gè)數(shù)肯定能滿足題意
就可以dpdpdp
設(shè)f[i][0]f[i][0]f[i][0]為前iii個(gè),第iii個(gè)沒(méi)修改,f[i][1]f[i][1]f[i][1],為前iii個(gè),第iii個(gè)修改了的最小值
轉(zhuǎn)移,直接看代碼

#include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int MAXN = 200000; int n,k,data[MAXN],f[MAXN][2]; int Abs(int x){return x>0?x:-x; } int main(){ios::sync_with_stdio(0);cin>>n>>k;for(int i=1;i<=n;i++)cin>>data[i];for(int i=1;i<=n;i++){if(i==1){f[i][1]=1;}else{if(Abs(data[i]-data[i-1])>=k){f[i][0]=min(f[i-1][0],f[i-1][1]);f[i][1]=min(f[i-1][0],f[i-1][1])+1;}else{f[i][0]=f[i-1][1];f[i][1]=min(f[i-1][0],f[i-1][1])+1;}}}cout<<min(f[n][0],f[n][1]);return 0; }

T3 烤面包片

傳送門


Solution

注意特判N=0N=0N=0mod=0mod=0mod=0的時(shí)候
剩下的可以發(fā)現(xiàn)nnn在很小的時(shí)候n!!!n!!!n!!!就比10910^9109大了
就可以暴力了
細(xì)節(jié)看代碼

#include<iostream> using namespace std; typedef long long ll; ll n,mod; ll ksc(ll a,ll b,ll p){ll ret = 0;while(b){if(b&1){ret = (ret+a)%p;}a = (a*2)%p;b>>=1;}return ret; } int main(){ios::sync_with_stdio(0);cin>>n>>mod;if(mod==1){cout<<0;return 0;}if(n==0){cout<<1;return 0;}ll cur = 1;for(ll i=n;i>=1;i--){double tmp = cur;tmp *= i;cur *= i;if(tmp>=mod){cout<<0;return 0;}}n = cur;cur = 1;for(ll i=n;i>=1;i--){double tmp = cur;tmp *= i;cur *= i;if(tmp>=mod){cout<<0;return 0;}}n = cur;cur = 1;for(ll i=n;i>=1;i--){cur = ksc(cur,i,mod);}cout<<cur;return 0; }

T4 茶顏悅色

傳送門


Solution

yyyy?ky-ky?k離散化
然后對(duì)xxx排序用掃描線
對(duì)于一個(gè)點(diǎn)可以發(fā)現(xiàn)它對(duì)底邊在[y?k,y][y-k,y][y?k,y]的正方形有貢獻(xiàn)
用線段樹維護(hù)貢獻(xiàn)值,相當(dāng)于區(qū)間加減和查詢?nèi)肿畲笾?/p> #include<bits/stdc++.h> using namespace std; const int MAXN = 2e5+10; int n,k; struct _{int x,y; }; _ data[MAXN]; int buf[MAXN],tot,tr[MAXN<<3],tag[MAXN<<3]; void pushup(int x){tr[x]=max(tr[x<<1],tr[x<<1|1]);} void pushdown(int x){tag[x<<1]+=tag[x];tag[x<<1|1]+=tag[x];tr[x<<1] += tag[x]; tr[x<<1|1] += tag[x]; tag[x]=0; } void Modify(int rt,int l,int r,int L,int R,int delta){pushdown(rt);int mid=(l+r)>>1;if(l==L&&r==R){tag[rt]=delta;tr[rt]+=delta;return;}if(R<=mid)Modify(rt<<1,l,mid,L,R,delta);else if(L>mid)Modify(rt<<1|1,mid+1,r,L,R,delta);else{Modify(rt<<1,l,mid,L,mid,delta);Modify(rt<<1|1,mid+1,r,mid+1,R,delta);}pushup(rt); } bool cmp(_ a,_ b){return a.x<b.x;} int main(){ios::sync_with_stdio(0);cin>>n>>k;for(int i=1;i<=n;i++){cin>>data[i].x>>data[i].y;buf[++tot]=data[i].y;buf[++tot]=data[i].y-k;}sort(buf+1,buf+1+tot);tot=unique(buf+1,buf+1+tot)-buf-1;sort(data+1,data+1+n,cmp);int l=1,ans=0;for(int i=1;i<=n;i++){int L=lower_bound(buf+1,buf+1+tot,data[i].y-k)-buf,R=lower_bound(buf+1,buf+1+tot,data[i].y)-buf;while(data[l].x+k<data[i].x){Modify(1,1,tot,lower_bound(buf+1,buf+1+tot,data[l].y-k)-buf,lower_bound(buf+1,buf+1+tot,data[l].y)-buf,-1);l++;}Modify(1,1,tot,L,R,1);ans=max(ans,tr[1]);}cout<<ans;return 0; }


T5 飛行棋

傳送門


Solution

正著不好做就倒著做,設(shè)起點(diǎn)為111,終點(diǎn)為d+1d+1d+1
設(shè)f[i]f[i]f[i]為從終點(diǎn)走到點(diǎn)iii的期望步數(shù),則f[1]f[1]f[1]就是最后的答案
因?yàn)樽詈蟮?span id="ozvdkddzhkzd" class="katex--inline">K+1K+1K+1個(gè)節(jié)點(diǎn)非常煩,可以直接高斯消元求出來(lái)(我求出來(lái)才發(fā)現(xiàn)有規(guī)律……)
然后對(duì)于一個(gè)不在最后K+1K+1K+1個(gè)節(jié)點(diǎn)之內(nèi)的點(diǎn)

∑j&gt;i且i+k&gt;=jf[j]/K+1=f[i]\sum_{j&gt;i且i+k&gt;=j}{f[j]/K}+1=f[i]j>ii+k>=j?f[j]/K+1=f[i]
就可以矩陣快速冪了,那個(gè)+1+1+1可以單獨(dú)開(kāi)一維保存常數(shù)
細(xì)節(jié)看代碼

#include<bits/stdc++.h> using namespace std; typedef long long ll; const int MAXK = 25; const int MOD=1e9+7; ll Exgcd(ll a,ll b,ll &x,ll &y){if(b==0){x=1;y=0;return a;}ll d=Exgcd(b,a%b,y,x);y-=a/b*x;return d; } ll GetInv(ll x){ll a,b;Exgcd(x,MOD,a,b);return (a+MOD)%MOD; } void update(ll &x){x%=MOD;x=(x+MOD)%MOD; } ll k,d,dishu; ll data[MAXK][MAXK]; struct Mar{ll a[MAXK][MAXK];Mar(){memset(a,0,sizeof a);}void clear(){memset(a,0,sizeof a);} }; Mar operator * (Mar x,Mar y){Mar c;for(int i=1;i<=k;i++){for(int j=1;j<=k;j++){for(int h=1;h<=k;h++){c.a[i][j]=(c.a[i][j]+(x.a[i][h]*y.a[h][j])%MOD)%MOD;}}}return c; } void Gauss(){ll n = k+1;data[n][n]=1;for(int i=1;i<n;i++){for(int j=1;j<=k;j++){int toward = i+j;if(toward > n){toward = n - (toward - n);}data[i][toward] += dishu;data[i][n+1] -= dishu;update(data[i][toward]);update(data[i][n+1]);}data[i][i]--;update(data[i][i]);} for(int i=1;i<=n;i++){if(data[i][i]==0)continue;ll inv = GetInv(data[i][i]);for(int j=1;j<=n+1;j++){data[i][j]=(data[i][j]*inv)%MOD;}for(int j=1;j<=n;j++){if(data[j][i]==0 || i==j)continue;ll D = data[j][i];for(int h=1;h<=n+1;h++){data[j][h] = (data[j][h] - data[i][h]*D)%MOD;update(data[j][h]);}}} }int main(){ios::sync_with_stdio(0);cin>>d>>k;dishu = GetInv(k);Gauss();if(d==k){cout<<data[1][k+2];return 0;}// k++; Mar Init; Init.clear();for(int i=k;i>=1;i--){Init.a[1][k-i+1] = data[i][k+2];}k++;Init.a[1][k] = 1;d -= (k-1);Mar Trans; Trans.clear();for(int i=1;i<k-1;i++){Trans.a[i+1][i]=1;}for(int i=1;i<k;i++){Trans.a[i][k-1]=dishu;}Trans.a[k][k-1]=1;Trans.a[k][k]=1;Mar I; I.clear();for(int i=1;i<=k;i++)I.a[i][i]=1;while(d){if(d&1){I=I*Trans;}Trans=Trans*Trans;d>>=1;}Init = Init * I;cout<<Init.a[1][k-1];return 0; }

T6 三元組

傳送門


Solution

發(fā)現(xiàn)那個(gè)不等式只可能有兩種成立方式
2(ai+aj)&lt;=bi+bj2(a_i+a_j)&lt;=b_i+b_j2(ai?+aj?)<=bi?+bj?
2(bi+bj)&lt;=ai+aj2(b_i+b_j)&lt;=a_i+a_j2(bi?+bj?)<=ai?+aj?
這兩種方式是不可能同時(shí)成立的(證明很顯然,不證了)
可以分別統(tǒng)計(jì)
把第一個(gè)式子分離一下有
2ai?bi&lt;=bj?2aj2a_i-b_i&lt;=b_j-2a_j2ai??bi?<=bj??2aj?
顯然可以分治或者離散化一下隨便找個(gè)數(shù)據(jù)結(jié)構(gòu)維護(hù)
第二種情況把a,ba,ba,b互換再做一次就好了
我不是知道我那根神經(jīng)抽了,寫的分治

#include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,a,b) for(int i=a;i>=b;i--) const int MOD = 1e9+7; const int MAXN = 1e5+2; typedef long long ll; struct _{ll a,b,c,v1,v2;int loc; }; _ data[MAXN],data2[MAXN]; int n; void Build(){rep(i,1,n){data[i].v1=2*data[i].a-data[i].b;data[i].v2=-data[i].v1;} } void Read(){cin>>n;rep(i,1,n){cin>>data[i].a>>data[i].b>>data[i].c;data[i].loc=i;} } _ buf[MAXN]; ll ans; void DAC(int l,int r){int mid=(l+r)/2;if(l==r){if(data[l].v1<=data[l].v2){ans = (ans + (data[l].c*data[l].c)%MOD)%MOD;}return;}DAC(l,mid);DAC(mid+1,r);int R = r;ll cur = 0;for(int i=mid;i>=l;i--){while(R>=mid+1 && data[i].v1 <= data2[R].v2){cur = (cur + data2[R].c)%MOD;R--;}ans = (ans + (cur * data[i].c)%MOD)%MOD;}int p1=l,p2=mid+1,tot=l;while(p1<=mid||p2<=r){if(p1<=mid&&p2<=r){if(data[p1].v1 < data[p2].v1){buf[tot++]=data[p1++]; }else{buf[tot++]=data[p2++];}}else if(p1<=mid){buf[tot++]=data[p1++];}else{buf[tot++]=data[p2++];}}rep(i,l,r)data[i]=buf[i];p1=l;p2=mid+1;tot=l;while(p1<=mid||p2<=r){if(p1<=mid&&p2<=r){if(data2[p1].v2 < data2[p2].v2){buf[tot++]=data2[p1++];}else{buf[tot++]=data2[p2++];}}else if(p1<=mid){buf[tot++]=data2[p1++];}else{buf[tot++]=data2[p2++];}}rep(i,l,r)data2[i]=buf[i]; } bool cmp(_ x,_ y){return x.loc < y.loc; } int main(){ios::sync_with_stdio(0);Read();Build();rep(i,1,n)data2[i]=data[i];DAC(1,n);sort(data+1,data+1+n,cmp);rep(i,1,n)swap(data[i].a,data[i].b);Build();rep(i,1,n)data2[i]=data[i];DAC(1,n);cout<<ans;return 0; }

T7 籃球校賽

傳送門


Solution

狀壓dpdpdp板子題,直接上代碼

#include<bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN = 1e5+2; ll f[MAXN][1<<5]; ll n,data[MAXN][6]; int main(){ios::sync_with_stdio(0);cin>>n;for(int i=1;i<=n;i++){for(int j=1;j<=5;j++){cin>>data[i][j];}}for(int i=1;i<=n;i++){for(int s=1;s<(1<<5);s++){f[i][s] = -0x3f3f3f3f3f3f3f3fLL;}}for(int i=1;i<=n;i++){for(int s=1;s<(1<<5);s++){f[i][s] = max(f[i][s],f[i-1][s]);for(int j=0;j<5;j++){if(s&(1<<j)){f[i][s] = max(f[i-1][s^(1<<j)]+data[i][j+1],max(f[i][s],f[i-1][s]));}}}}cout<<f[n][(1<<5)-1];return 0; }

T8 分配學(xué)號(hào)

傳送門


Solution

可能是我計(jì)數(shù)能力太弱了,我感覺(jué)這是最難的一道題。
首先最后的完成的序列排序后一定是由一段又一段連續(xù)的數(shù)構(gòu)成的,不然沒(méi)法保證次數(shù)最小。
所以排序后從小到大貪心。
如果能構(gòu)成一段連續(xù)的數(shù)那就不管,如果不行就要開(kāi)始改變學(xué)號(hào)。
現(xiàn)在只考慮一段需要修改成一段連續(xù)的數(shù)的序列
比如1,1,1,11,1,1,11,1,1,1
又貪心
最后一定是
1,2,3,41,2,3,41,2,3,4
總的代價(jià)等于最后的代數(shù)和-最初的代數(shù)和,所以只需要給最初的序列進(jìn)行排列,然后依次賦值就行了。
可是題目還有一個(gè)條件是,修改后的學(xué)號(hào)一定要變大。

那么對(duì)于這樣一段序列,我們對(duì)每個(gè)數(shù)減去(第一個(gè)數(shù)-1),化成以數(shù)值1開(kāi)頭的序列a[i]a[i]a[i]
這樣問(wèn)題就變成了
問(wèn)有多少個(gè)排列b[i]b[i]b[i],使得一個(gè)數(shù)jjjb[i]b[i]b[i]中的位置大于等于a[j]a[j]a[j]
用插空法計(jì)數(shù),設(shè)f[i]f[i]f[i]為前iii個(gè)數(shù)的答案
f[i]=f[i?1]?(i?a[i]+1)f[i] = f[i-1]*(i-a[i]+1)f[i]=f[i?1]?(i?a[i]+1)
意思是第iii個(gè)數(shù)最靠前可以插在原來(lái)第a[i]a[i]a[i]個(gè)數(shù)的前面,讓它的排名至少為a[i]a[i]a[i]
然后一共有iii個(gè)位置。
說(shuō)了這么多,代碼卻那么短

#include<bits/stdc++.h> using namespace std; typedef long long ll; const int MOD = 1e9+7; const int MAXN = 1e5+2; int n; ll data[MAXN]; int main(){ios::sync_with_stdio(0);cin>>n;for(int i=1;i<=n;i++){cin>>data[i];}sort(data+1,data+1+n);ll ans = 1;for(int j,i=1;i<=n;i=j){for(j=i+1;j<=n&&data[j]<data[i]+j-i;j++){ans = ans * (data[i]+j-i-data[j]+1) % MOD;} }cout<<ans;return 0; }

T9 Gree的心房

傳送門


Solution

很容易發(fā)現(xiàn)答案的下界是n+m?2n+m-2n+m?2,走最上面一行和最右邊一列。
然后障礙物最多有(n?1)?(m?1)(n-1)*(m-1)(n?1)?(m?1)個(gè)。

#include<iostream> using namespace std; typedef long long ll; ll n,m,k; int main(){cin>>n>>m>>k;if(k>((n-1)*(m-1))){cout<<-1;}else{cout<<n-1+m-1;}return 0; }

總結(jié)

以上是生活随笔為你收集整理的CCPC-Wannafly Comet OJ 夏季欢乐赛(2019)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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