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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

NOIP赛前模拟20171027总结

發(fā)布時間:2023/11/30 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NOIP赛前模拟20171027总结 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目:

1.壽司

? 給定一個環(huán)形的RB串··要求經(jīng)過兩兩互換后RB分別形成兩段連續(xù)區(qū)域,求最少操作次數(shù)(算法時間O(n))

2.金字塔

? 給定一個金字塔的側(cè)面圖有n層··已知每一層的寬度··高度均為1··要求在圖中取出恰好K個互不相交的矩形(邊緣可以重疊),求最多可以取出多少面積

? n<=20000,k<=100

3.心靈治愈

? 給定n,m要求取出不大于m的n個正整數(shù),問有多少種取法使n個數(shù)和m的最大公因數(shù)為1,n,m<=10^15

題解:

1.分析

? 首先為了方便我們把環(huán)從中間斷開看成一個序列,我們考慮如果移動R串··那么肯定是找到某一B為中心··B的左邊R移到一起··B的右邊R移到一起(這里描述有點模糊···如果序列左邊的R都移到一起,且序列最左邊為R,右邊同理··則實際在環(huán)中R肯定是連續(xù)的一段··)

? 因此我們先隨意找一個B為中心··然后計算答案··之后我們一次將序列最左端的字符移到最右端(比如序列BBRRR移動后就變成BRRRB)然后考慮答案的變化即可···具體實現(xiàn)參見代碼

#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<cstring> #include<string> #include<algorithm> using namespace std; const int N=2e6+5; int T,n,num[N]; char s[N]; int main() {//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);scanf("%d",&T);while(T--){long long ans=0,cnt=0;int tot1=0,tot2=0,totl=0,totr=0,mid;scanf("%s",s+1);n=strlen(s+1);for(int i=1;i<=n;i++){if(s[i]=='B') num[i]=num[i+n]=1,tot1++;else num[i]=num[i+n]=2,tot2++;}int half=(tot1+1)/2;int temp=0;for(int i=1;i<=n;i++){if(num[i]==1) {temp++;if(temp==half) mid=i;}else{if(temp<half){totl++;cnt+=temp;}else {totr++;cnt+=(tot1-temp);}}}ans=cnt;for(int i=1;i<n;i++){if(num[i]==1){ int tot=0,j;for(j=mid+1;num[j]!=1;j++) tot++; cnt-=totl;cnt+=(totr-tot);mid=j;totl+=tot;totr-=tot;if(tot1%2==0) cnt-=tot;ans=min(ans,cnt);}else {totl-=1;totr+=1; }}cout<<ans<<endl;}return 0; }

?

2.dp+決策單調(diào)性/斜率優(yōu)化

? dp方程肯定很好想··第一要明確取的方案··我們肯定是以某一層的寬度為矩形的一邊··然后往下取到某一層為一個矩形·矩形的高就是兩層高的差··

? 然后設(shè)f[j][i]為第j塊矩形以第i層為一邊的最大面積··轉(zhuǎn)移方程即為:

??f[j][i]=max(f[j][i],f[k][i-1]+(long long)len[j]*(j-k));

??其中k為我們往下枚舉的層數(shù)··len為j層的寬度··

? 然后通過打表(dalao也可以分析)得出該方程滿足決策單調(diào)性且使用于斜率優(yōu)化····這里兩種方法都能過

? 決策單調(diào)性:

#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<string> #include<cstring> #include<algorithm> using namespace std; inline int R() {char c;int f=0;for(c=getchar();c<'0'||c>'9';c=getchar());for(;c<='9'&&c>='0';c=getchar()) f=(f<<3)+(f<<1)+c-'0';return f; } const int N=20005; const int M=105; struct node {int l,r,pos; }Que[N]; int n,K; long long len[N],f[N][M]; inline long long calc(int i,int j,int now) {return f[j][now-1]+(long long)len[i]*(i-j); } inline int find(node a,int b,int now) {int le=a.l,ri=a.r,ans=a.r+1;while(le<=ri){int mid=(le+ri)/2;if(calc(mid,b,now)>calc(mid,a.pos,now)) ri=mid-1,ans=mid;else le=mid+1;}return ans; } inline void dp(int now) {int Head=1,Tail=0;node tmp;tmp.l=now;tmp.r=n;tmp.pos=now-1;Que[++Tail]=tmp;for(int i=now;i<=n;i++){while(Que[Head].r<i) Head++;f[i][now]=calc(i,Que[Head].pos,now);if(calc(n,i,now)>calc(n,Que[Tail].pos,now)){while(Head<=Tail&&calc(Que[Tail].l,i,now)>calc(Que[Tail].l,Que[Tail].pos,now)) Tail--;if(Head<=Tail){int t=find(Que[Tail],i,now);Que[Tail].r=t-1;node tmp;tmp.l=t,tmp.r=n,tmp.pos=i;Que[++Tail]=tmp;}else{node tmp;tmp.l=i+1;tmp.r=n;tmp.pos=i;Que[++Tail]=tmp;}}} } int main() {//freopen("pyramid.out","w",stdout);n=R(),K=R();int x,y;if(n<=1000){ for(int i=1;i<=n;i++){x=R(),y=R();len[i]=y-x+1;f[i][1]=(long long)len[i]*i;}for(int i=2;i<=K;i++)for(int j=i;j<=n;j++)for(int k=i-1;k<j;k++) f[j][i]=max(f[j][i],f[k][i-1]+(long long)len[j]*(j-k));long long ans=0;for(int i=K;i<=n;i++) ans=max(f[i][K],ans);cout<<ans<<"\n";}else{for(int i=1;i<=n;i++){x=R(),y=R();len[i]=y-x+1;f[i][1]=(long long)len[i]*i;}for(int i=2;i<=K;i++)dp(i);long long ans=0;for(int i=K;i<=n;i++) ans=max(f[i][K],ans); cout<<ans<<"\n";}return 0; }

?

3.質(zhì)因數(shù)分解+容斥原理

? 這道題和之前跳蚤的那道題是一模一樣的··這里就并不多說了··

? 唯一注意的是我發(fā)現(xiàn)了自己快速冪的一個漏洞··求a^b之前要將a取模···之前一直沒有注意到···還有就是注意最后答案為負的問題

#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<cstring> #include<string> #include<algorithm> #include<vector> using namespace std; vector<long long>zhiyinzi; const long long mod=1e9+7; long long n,m,ans=0; inline long long ksm(long long a,long long b) {long long ans=1;a%=mod; while(b){if(b%2==1) ans=(ans*a)%mod;b/=2;a=(a*a)%mod;}return ans; } inline void dfs(int u,long long tot,long long f) {if(u==zhiyinzi.size()){long long temp=m/tot;ans=(ans+f*ksm(temp,n))%mod;ans=(ans%mod+mod)%mod;return;}dfs(u+1,tot,f);dfs(u+1,tot*zhiyinzi[u],-f); } int main() {scanf("%I64d%I64d",&n,&m);long long temp=m;for(long long i=2;i*i<=m;i++){if(i>temp) break; if(temp%i==0){ while(temp%i==0) temp/=i;zhiyinzi.push_back(i);}}if(temp!=1) zhiyinzi.push_back(temp);dfs(0,1,1);ans=(ans%mod+mod)%mod;cout<<ans<<endl;return 0; }

?

?

??

轉(zhuǎn)載于:https://www.cnblogs.com/AseanA/p/7745338.html

總結(jié)

以上是生活随笔為你收集整理的NOIP赛前模拟20171027总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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