Noip模擬45 2021.8.21


一定別刪大括號,檢查是;還是,

ceil函數里面要寫double,否則根本沒用!!!!!!!

T1 打表

正解:打表

考場上很難真正把柿子理解着推出來

況且想要理解題意就很難,比如我就理解錯了

半猜着讀題思考,結果啥也不對

首先,柿子是:

$\frac{\sum_{i=1}^{2^k-1}|A_i-A_{ans}|}{2^k}$

證明用歸納法:

設$P_i$表示還有$i$個位置沒有確定,期望值是剩下的數與正確輸出差的平均值,也就是先假設答案的那個柿子正確

當$i=1$時,$P_1$是對的,比較好想

然后推廣到$P_{i-1}$,這時的狀態是比$P_i$少確定一位,這時兩個$CPU$會選擇同一個位置到$P_i$的狀態,

那么他們的決策一定是相反的因為剩下的數與正確輸出差的和是一定的

因此$P_i$也是正確的,因為選擇同一位相當於將剩下的數分為了兩個不相交集合

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 namespace AE86{
 5     inline int read(){
 6         int x=0,f=1;char ch=getchar();
 7         while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 8         while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
 9     }inline void write(int x,char opt='\n'){
10         char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
11         do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
12         for(int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
13 }using namespace AE86;
14 
15 const int NN=3e5+5,p=1e9+7;
16 int k,ans,a[NN],sum;
17 
18 inline int qmo(int a,int b){
19     int ans=1,c=p; a%=c;
20     while(b){
21         if(b&1) ans=(ans*a)%c;
22         b>>=1; a=(a*a)%c;
23     }return ans;
24 }
25 
26 namespace WSN{
27     inline short main(){
28         k=read();ans=read();
29         for(int i=0;i<(1<<k);i++)a[i]=read();
30         for(int i=0;i<(1<<k);i++)
31             (sum+=abs(a[i]-a[ans]))%=p;
32         write(sum*qmo(qmo(2,k),p-2)%p);
33         return 0;
34     }
35 }
36 signed main(){return WSN::main();}
View Code

 

T2 蛇

黑色神題

首先要明白蛇的路徑一定是這樣的:

本圖片粘貼自學長博客

然后分段考慮,

首先頭部和尾部的兩段往返可以用哈希處理出來,

然后考慮中間的扭動部分

設$dp_{i,j,k}$表示位置是$(i,j)$的時候匹配串長度為$k$的方案數,

然后進行$dp$的時候親定一個方向,$dp$上面再加一維表示上下走還是左右走

這樣的話做完一遍后把字符串反轉再來一遍就行

至於考場上為了壓行讓代碼變得好看誤把大括號刪掉痛失$30$分就讓人很難受。。。。。。。

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 #define ULL unsigned long long
 4 #define zheng 0
 5 #define fannn 1
 6 using namespace std;
 7 namespace AE86{
 8     inline int read(){
 9         int x=0,f=1;char ch=getchar();
10         while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
11         while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
12     }inline void write(int x,char opt='\n'){
13         char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
14         do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
15         for(int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
16 }using namespace AE86;
17 
18 const int NN=2005,p=1e9+7;
19 const ULL base=131;
20 int n,m,a[2][NN],b[NN],dp[2][NN][NN<<1][2],ans;
21 char ch[NN];
22 ULL pw[NN],haa[2][NN][2],hab[NN];
23 inline void init(){
24     scanf("%s",ch+1);n=strlen(ch+1);
25     pw[0]=1; for(int i=1;i<=max(m,n);i++) pw[i]=pw[i-1]*base;
26     for(int i=1;i<=n;i++) a[0][i]=ch[i]-'a'+1;
27     scanf("%s",ch+1);for(int i=1;i<=n;i++) a[1][i]=ch[i]-'a'+1;
28     scanf("%s",ch+1);m=strlen(ch+1);
29     for(int i=1;i<=m;i++){
30         b[i]=ch[i]-'a'+1;
31         hab[i]=hab[i-1]*base+(ULL)b[i];
32     }
33 }
34 inline ULL ask(int x,int fx,int l,int r){
35     if(fx==zheng) return haa[x][r][zheng]-haa[x][l-1][zheng]*pw[r-l+1];
36     else return haa[x][r][fannn]-haa[x][l+1][fannn]*pw[l-r+1];
37 }
38 inline ULL get(int l,int r){return hab[r]-hab[l-1]*pw[r-l+1];}
39 inline void calc(){
40     for(int i=0;i<2;i++){
41         for(int j=1;j<=n;j++)
42             haa[i][j][zheng]=haa[i][j-1][zheng]*base+(ULL)a[i][j];
43         for(int j=n;j>=1;j--)
44             haa[i][j][fannn]=haa[i][j+1][fannn]*base+(ULL)a[i][j];
45     }
46     for(int i=0;i<2;i++) for(int j=1;j<=n;j++){
47         dp[i][j][1][0]=(a[i][j]==b[1]);
48         for(int k=2;k<=j;k++)
49             dp[i][j][k<<1][1]=((ask(i^1,fannn,j,j-k+1)==get(1,k))&&(ask(i,zheng,j-k+1,j)==get(k+1,k<<1)));
50     }
51     for(int k=1;k<=m;k++) for(int i=0;i<2;i++)
52         for(int j=1;j<=n;j++) if(a[i][j]==b[k]){
53             (dp[i][j][k][0]+=dp[i][j-1][k-1][0]+dp[i][j-1][k-1][1])%=p;
54             (dp[i][j][k][1]+=dp[i^1][j][k-1][0])%=p;
55         }
56     for(int i=0;i<2;i++) for(int j=1;j<=n;j++) for(int k=0;k<=m;k++){
57         int res=(m-k)>>1; if(((m-k)&1)==1||res==1) continue;
58         if(m==k||(j+res<=n&&ask(i,zheng,j+1,j+res)==get(k+1,k+res)&&ask(i^1,fannn,j+res,j+1)==get(m-res+1,m)))
59         (ans+=dp[i][j][k][0]+dp[i][j][k][1])%=p;
60     }
61 }
62 
63 namespace WSN{
64     inline short main(){
65         init();
66         calc();
67         reverse(a[0]+1,a[0]+n+1);
68         reverse(a[1]+1,a[1]+n+1);
69         memset(dp,0,sizeof(dp));
70         calc();
71         if(m==1){
72             for(int i=0;i<2;i++) for(int j=1;j<=n;j++)
73                 ans-=(a[i][j]==b[1]);
74         }
75         if(m==2){
76             for(int i=0;i<2;i++) for(int j=1;j<=n;j++)
77                 ans-=(a[i][j]==b[1]&&a[i^1][j]==b[2]);
78         }write(ans);
79         return 0;
80     }
81 }
82 signed main(){return WSN::main();}
View Code

 

T3 購物

考場上想到正解,結果無法給出證明就遺憾收場了,因為怕爆零

可是因為$ceil$沒有用$double$還是爆零了。。。。

每個數都有一個關於$k$的取值范圍區間

發現加上一個數后他和原來的區間一定會產生交集

然后邊維護前綴和,邊判斷有幾段區間沒有重疊,減去沒有重疊的部分就是$k$的覆蓋范圍

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 namespace AE86{
 5     inline int read(){
 6         int x=0,f=1;char ch=getchar();
 7         while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 8         while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
 9     }inline void write(int x,char opt='\n'){
10         char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
11         do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
12         for(int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
13 }using namespace AE86;
14 
15 const int NN=1e5+5;
16 int n,a[NN],ans,sum,jian;
17 namespace WSN{
18     inline short main(){
19         n=read();
20         for(int i=1;i<=n;i++) a[i]=read(),sum+=a[i];
21         sort(a+1,a+n+1);
22         for(int i=1;i<=n;i++){
23             int l=ceil(a[i]/2.0),r=a[i];
24             int ll=ceil(a[i-1]/2.0),rr=a[i-1];
25             if(rr<l) jian+=l-rr-1;
26             a[i]+=a[i-1];
27         }
28         write(sum-jian);
29         return 0;
30     }
31 }
32 signed main(){return WSN::main();}
View Code

 

T4 ants

正解是回滾莫隊。。。。絲毫沒學過

然后下午就是又開始學習知識,竟是$OJ$上的一道原題

連樣例都一樣。。。。

每一個塊內維護兩個數組,$lb_i$,$rb_i$,是以值為下標的數組

表示$i$的左邊的連續編號,右邊的連續編號長度

在移動指針的時候維護最大的連續編號長度就行,注意重點在清除

開個棧記錄更新的點和原始權值,最后只清空更改過的就行

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 namespace AE86{
 5     inline int read(){
 6         int x=0,f=1;char ch=getchar();
 7         while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 8         while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
 9     }inline void write(int x,char opt='\n'){
10         char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
11         do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
12         for(int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
13 }using namespace AE86;
14 
15 const int NN=1e5+5;
16 int n,m,a[NN],top,sq;
17 int ls[NN],rs[NN],res[NN];
18 
19 struct SNOW{int l,r,k,id;}q[NN];
20 struct stac{int pos,val;}stk[NN];
21 
22 inline bool cmp(SNOW a,SNOW b){return a.k==b.k?a.r<b.r:a.l<b.l;}
23 
24 namespace WSN{
25     inline short main(){
26 //        freopen("1.in","r",stdin);
27         n=read();m=read();sq=sqrt(n);
28         for(int i=1;i<=n;i++) a[i]=read();
29         for(int i=1;i<=m;i++){
30             int l=read(),r=read();
31             q[i]=(SNOW){l,r,(l-1)/sq+1,i};
32         }
33         sort(q+1,q+m+1,cmp);
34         
35         int l=1,r=0,ans=0;
36         for(int i=1;i<=m;i++){
37             int ql=q[i].l,qr=q[i].r;
38             if(q[i].k!=q[i-1].k){
39                 memset(ls,0,sizeof(ls));
40                 memset(rs,0,sizeof(rs));
41                 l=r=q[i].k*sq; ans=0;
42             }
43             while(r<qr){
44                 ++r;
45                 ls[a[r]]=ls[a[r]-1]+1;
46                 rs[a[r]]=rs[a[r]+1]+1;
47                 int len=ls[a[r]]+rs[a[r]]-1;
48                 int L=a[r]-ls[a[r]]+1;
49                 int R=a[r]+rs[a[r]]-1;
50                 ls[R]=rs[L]=len;
51                 ans=max(ans,len);
52             }
53             int tmp=ans; top=0;
54             for(int j=ql;j<=min(qr,l);j++){
55                 ls[a[j]]=ls[a[j]-1]+1;
56                 rs[a[j]]=rs[a[j]+1]+1;
57                 int len=ls[a[j]]+rs[a[j]]-1;
58                 int L=a[j]-ls[a[j]]+1;
59                 int R=a[j]+rs[a[j]]-1;
60                 stk[++top]=(stac){R,ls[R]};
61                 stk[++top]=(stac){L,rs[L]};
62                 ls[R]=rs[L]=len;
63                 tmp=max(tmp,len);
64             }
65             for(int j=top;j;j--)
66                 if(j&1) ls[stk[j].pos]=stk[j].val;
67                 else rs[stk[j].pos]=stk[j].val;
68             for(int j=ql;j<=min(qr,l);j++)
69                 ls[a[j]]=rs[a[j]]=0;
70             res[q[i].id]=tmp;
71         }
72         for(int i=1;i<=m;i++) write(res[i]);
73         return 0;
74     }
75 }
76 signed main(){return WSN::main();}
View Code

 

麻辣燙真香!!!!!!!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM