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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

NOIP模拟测试38「金·斯诺·赤」

發布時間:2023/12/2 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NOIP模拟测试38「金·斯诺·赤」 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

輾轉相減見祖宗

高精

#include<bits/stdc++.h> using namespace std; #define A 2000 #define P 1 #define N 10 #define ll long long ll n,T; char sjdfj[A]; struct bignum {ll n[A],l;bignum(){l=1,memset(n,0,sizeof(n));}void clear(){while(l>1&&!n[l-1]) l--;}void print(){printf("%lld",n[l-1]);for(ll i=l-2;i>=0;i--){printf("%0*lld",P,n[i]);}printf("\n");}void read(){l=0;scanf("%s",sjdfj+1);l=strlen(sjdfj+1);reverse(sjdfj+1,sjdfj+l+1);for(ll i=0;i<l;i++){n[i]=sjdfj[i+1]-'0';}}ll ok(){//若為0 return1 //若%2==0 return2//若%2!=0 return3if(n[0]==0&&l==1) return 1; // if(n[0]==1&&l==1) return 1;if(n[0]%2==0) return 2;if(n[0]%2!=0) return 3;}bool operator <(bignum x) const{bignum t=*this,tep;if(t.l!=x.l) return t.l<x.l;for(ll i=t.l-1;i>=0;i--){if(t.n[i]!=x.n[i]) return t.n[i]<x.n[i];}return 0;}bool operator >(bignum x) const{bignum t=*this;if(t.l!=x.l) return t.l>x.l;for(ll i=t.l-1;i>=0;i--){if(t.n[i]!=x.n[i]) return t.n[i]>x.n[i];}return 0;}bignum operator -(bignum x) const{bignum t=*this;if(t<x) swap(t,x);ll jie=0;// t.print();x.print();for(ll i=0;i<t.l;i++){t.n[i]-=x.n[i];while(t.n[i]<0){t.n[i]+=N;jie++;}t.n[i+1]-=jie;jie=0;}while(!t.n[t.l-1]&&t.l>1) t.l--;return t;}bignum operator *(bignum x) const{bignum t=*this,tep;tep.l=t.l+x.l+1;for(ll i=0;i<t.l;i++)for(ll j=0;j<x.l;i++){tep.n[i+j]+=t.n[i]*x.n[j];}for(ll i=0;i<tep.l;i++){if(tep.n[i]>=N) {tep.n[i+1]+=tep.n[i]/N;tep.n[i]%=N;}}tep.clear();return tep;}bignum operator +(bignum x)const{bignum t=*this;if(t.l<x.l) t.l=x.l;t.l++;for(ll i=0;i<t.l;i++){t.n[i]+=x.n[i];if(t.n[i]>=N){t.n[i+1]+=t.n[i]/N;t.n[i]%=N;}}t.clear();return t;}bignum operator =(ll x){l=0;while(x){n[l++]=x%N;x/=N;}return *this;}bignum operator *(const ll &b){bignum t=*this,r;r.l=0;ll g=0;for(ll i=0;i<t.l||g;i++){ll x;if(i<t.l)x=t.n[i]*b+g;else x=g;r.n[r.l++]=x%N;g=x/N;}return r;}bignum operator /(const ll &x){bignum t=*this,r;ll tmp=0;r.l=t.l;for(ll i=t.l-1;i>=0;i--){tmp+=t.n[i];if(tmp>=x){r.n[i]=tmp/x;tmp%=x;}tmp*=N;}r.clear();return r;} }a,b,c; ll gcd(){//若為0 return1 //若%2==0 return2//若%2!=0 return3while((a.ok()!=1&&b.ok()!=1)){ // printf("a=%lld ",a.ok()); // a.print(); // printf("b=%lld ",b.ok()); // b.print();ll ok1=a.ok(),ok2=b.ok();if(ok1==2&&ok2==2){return 0;a=a/2,b=b/2;}else if(ok1==3&&ok2==3){if(a<b) swap(a,b);a=a-b;}else if(ok1==2&&ok2==3){a=a/2;}else if(ok1==3&&ok2==2){b=b/2;}} } int main() {/*1 1023 3072*/ // freopen("bf.txt","w",stdout);scanf("%lld",&T);for(ll i=1;i<=T;i++){a.read(),b.read();// a=a-b; gcd(); // a.print(),b.print();if(a.n[0]==0&&b.n[0]==1&&b.l==1&&a.l==1){printf("Yes\n");}else if(a.n[0]==1&&b.n[0]==0&&b.l==1&&a.l==1){printf("Yes\n");}else printf("No\n");} } View Code

斯諾

考試代碼改了改,數組開小見祖宗

考試時候$re$了

?

?

?

?

?大概就是這樣

考試時也維護的前綴和

$60\%$算法

只含$0,1$

我們可以將$0$看作減$1$,$1$看作加一

那么合法方案數就是$sum[r]-sum[l-1]==0$的個數

我們開一個桶存$sum[l]$,那么當前符合就是桶里$sum[i]$個數

查完個數再把$sum[r]$壓進桶就行了

注意初始化,當你$sum==0$時也是合法方案,方案數為桶里$sum==0$個數$+1$,你可以先在桶里$0$壓一個再進行操作

代碼

#include<bits/stdc++.h> using namespace std; #define ll long long #define mod 5000000 ll tong[mod+mod+mod+mod],sum[mod+mod][3],sumtp[21111111],sum2[111111111]; ll n,ans=0,all; char a[mod+mod]; void solve(ll ql,ll qr){if(ql==qr) return ;ll mid=(ql+qr)>>1;solve(ql,mid);solve(mid+1,qr);ans=rand(); } ll check(ll l,ll r){ll len=(r-l+1)/2; // printf("l=%lld r=%lld len=%lld\n",l,r,len); // printf("sum0=%lld 1=%lld 2=%lld\n",sum[r][0]-sum[l-1][0],sum[r][1]-sum[l-1][1],sum[r][2]-sum[l-1][2]);if(sum[r][0]-sum[l-1][0]>len) return 0;if(sum[r][1]-sum[l-1][1]>len) return 0;if(sum[r][2]-sum[l-1][2]>len) return 0;return 1; } int main(){scanf("%lld",&n);scanf("%s",a+1);all=1;for(ll i=1;i<=n;i++){sum[i][0]=sum[i-1][0];sum[i][1]=sum[i-1][1];sum[i][2]=sum[i-1][2];if(a[i]=='0') sum[i][0]++;if(a[i]=='1') sum[i][1]++;if(a[i]=='2') sum[i][2]++,all=0;}if(all&&n>1000){tong[mod]=1;for(ll i=1;i<=n;i++){sumtp[i]=sumtp[i-1];if(a[i]=='0') { // if(a[i-1]=='1') sumtp[i]=0; // if(sumtp[i]<0) ans++;sumtp[i]++;}else { // if(a[i-1]=='0') sumtp[i]=0; // if(sumtp[i]>0) ans++;sumtp[i]--;}}for(ll i=1;i<=n;i++){ans+=tong[mod+sumtp[i]];tong[mod+sumtp[i]]++; // printf("sumtp=%lld\n",sumtp[i]); }printf("%lld\n",ans);return 0;}if(n<=1000)for(ll i=1;i<=n;i++){for(ll j=i+1;j<=n;j++){if(check(i,j)){ans++;}}}else solve(1,n);printf("%lld\n",ans); } View Code

從$40\%$算法尋找思路

$60\%$算法$2$

維護三個$sum$,當為$0$,$sum[0]-- sum[1]++ sum[2]++$這樣就又和上面類似了

然而合法方案數不止$sum[r]-sum[l-1]==0$

合法很難維護找非法的,最后答案就是合法減非法

發現非法$sum$相減肯定$<0$

那么就轉化為逆序對問題

樹狀數組求逆序對

(其實你常數優秀可以$AC$

$100\%$算法

發現前后差異不大,假設你當前答案$1$為QAQ,若這一位仍為$1$,答案就要對應$-$,另外$2$,$0$答案就要$+$

?

轉載于:https://www.cnblogs.com/znsbc-13/p/11480024.html

總結

以上是生活随笔為你收集整理的NOIP模拟测试38「金·斯诺·赤」的全部內容,希望文章能夠幫你解決所遇到的問題。

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