1. 程式人生 > 其它 >Noip模擬51 2021.9.12

Noip模擬51 2021.9.12

T1 茅山道術 T2 泰拳警告 T3 萬豬拱塔 T4 抑鬱刀法

T1 茅山道術

考場上卡在了一個噁心的地方,

當時以為每次施法都會產生新的可以施法的區間,然後想都沒細想,

認為不可做,甚至$dfs$也無法打,考後一問發現是自己想多了。。

新產生的區間對答案根本沒有貢獻,還是可以按照原來的相同的顏色搞,

於是無論是$dfs$也好,$dp$也罷,都不用考慮新產生區間的後效性問題

那麼我們設$dp_i$表示處理到第$i$個寶石,然後判斷一下他的前面有無與他同色的寶石

轉移維護字首和即可。

 1 #include<bits/stdc++.h>//分治+dp?
 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(register int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);} 13 }using namespace AE86; 14 15 const int NN=1e6+5,mod=1e9+7; 16 int n,tot,a[NN],pre[NN];
17 namespace tree_array{ 18 int tr[NN]; 19 inline int lowbit(int x){return x&(-x);} 20 inline void update(int x,int v){for(int i=x;i<NN;i+=lowbit(i))(tr[i]+=v)%=mod;} 21 inline int query(int x){int ans=0;for(int i=x;i;i-=lowbit(i))(ans+=tr[i])%=mod;return ans;} 22 }using namespace tree_array; 23 24 namespace WSN{ 25 inline short main(){ 26 freopen("magic.in","r",stdin); 27 freopen("magic.out","w",stdout); 28 n=read(); 29 for(int i=1;i<=n;i++) a[i]=read(); 30 for(int i=1;i<=n;i++) 31 if(a[i]!=a[i-1]) a[++tot]=a[i]; 32 n=tot;update(1,1); 33 for(int i=1;i<=n;i++){ 34 if(pre[a[i]]) update(i,query(pre[a[i]])); 35 pre[a[i]]=i; 36 } 37 write(query(n)); 38 return 0; 39 } 40 } 41 signed main(){return WSN::main();}
View Code

T2 泰拳警告

本場考試最大失誤點

考場:

  $woc$概率題,好像是$dp$,跳了跳了。。。

考後:

  (看題解),啥?數學????

然後自己五分鐘推柿子敲對了就$A$了

還是太弱,無法看出題型。。。太弱了。。。。

不難得出:

$ans= \sum_{i=0}^{n-1} (\frac{1}{p+2})^{n-i} *(\frac{p}{p+2})^i *(n+1) *\sum_{j=0}^{j=\frac{n-i}{2}} C_{n-i}^{j}$

然後發現後面的組合數加和可以輕鬆的使用楊輝三角每一行的對稱性給它搞掉,就注意一下奇偶的細節即可

剩下的都能預處理,不預處理也可以卡過,只不過會拿最劣解(比如我)

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 const int mod=998244353,NN=3e6+5;
 5 namespace AE86{
 6     inline int read(){
 7         int x=0,f=1;char ch=getchar();
 8         while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 9         while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
10     }inline void write(int x,char opt='\n'){
11         char ch[20];int len=0;if(x<0)x=~x+1,putchar('-');
12         do{ch[len++]=x%10+(1<<5)+(1<<4);x/=10;}while(x);
13         for(register int i=len-1;i>=0;--i)putchar(ch[i]);putchar(opt);}
14     inline int qmo(int a,int b){
15         if(!a) return 1;
16         int ans=1,c=mod; a%=c;
17         while(b){
18             if(b&1) ans=ans*a%c;
19             b>>=1; a=a*a%c;
20         }
21         return ans;
22     }
23 }using namespace AE86;
24 
25 int n,p,inv,ans,v2,tmp,res;
26 int h[NN],v[NN],mi[NN],p1[NN],p2[NN];
27 inline void pre(){
28     h[0]=h[1]=1; v[0]=v[1]=1; mi[0]=p1[0]=p2[0]=1;
29     for(int i=2;i<NN;i++) h[i]=h[i-1]*i%mod;
30     v[NN-1]=qmo(h[NN-1],mod-2);
31     for(int i=NN-2;i>=2;i--) v[i]=v[i+1]*(i+1)%mod;
32     for(int i=1;i<=n;i++){
33         mi[i]=mi[i-1]*2%mod;
34         p1[i]=p1[i-1]*p%mod*inv%mod;
35         p2[i]=p2[i-1]*inv%mod;
36     }
37 }
38 inline int C(int n,int m){
39     if(n<m||n<0||m<0) return 0;
40     return h[n]*v[n-m]%mod*v[m]%mod;
41 }
42 
43 namespace WSN{
44     inline short main(){
45         freopen("fight.in","r",stdin);
46         freopen("fight.out","w",stdout);
47         n=read(); p=read(); inv=qmo(p+2,mod-2); v2=qmo(2,mod-2);
48         pre();
49         for(int i=0;i<n;++i){
50             tmp=p1[i]*(i+1)%mod*p2[n-i]%mod*C(n,i)%mod;
51             if((n-i)&1){
52                 res=mi[n-i]*v2%mod;
53                 ans=(ans+tmp*res%mod)%mod;
54             }
55             else{
56                 res=(mi[n-i]-C(n-i,(n-i)/2)+mod)%mod*v2%mod;
57                 ans=(ans+tmp*res%mod)%mod;
58             }
59         }
60         write(ans);
61         return 0;
62     }
63 }
64 signed main(){return WSN::main();}
View Code

T3 萬豬拱塔

$sb$細節題

考慮列舉權值$[l,r]$的一段區間,將編號在這一段的格子染黑,然後判斷黑色是否可以構成一個矩形

我們可以搞出來$(n+1)*(m+1)$ 個$2*2$的小方塊覆蓋整個矩陣(在邊緣外的也算),可以發現:

能夠成一個矩形,當且僅當 有$4$個小方塊只覆蓋$1$個黑格子,沒有小方塊覆蓋恰好$3$個黑格子

要維護$2*2$的小方塊:

記$kua[i][5]$為編號為$i$的小方塊裡面四個格子的權值,因為列舉權值區間的過程是單調遞增的

所以將塊內的權值排序,這就是他們被染色的順序,然後按照順序依次線上段樹上$+1,-1$操作即可

設$f(l)$表示在$[l,r]$區間內有多少個小方塊包含$1$個或$3$個黑格子,

線段樹上維護: $f(l)$的最小值,最小值數目,以及造成最小值的$l$的和。

剛才維護小方塊所說的操作就是對最小值的操作

那麼最後的答案可以通過維護的值算出。