[考試反思]0514省選模擬96:對比

來了。又是越考越差的時段。

和昨天是一個出題人,心態先崩一半。

$T1$有了點部分分剩下的還是沒有。依然沒有構造。依然出現原題($T3$是倉鼠雜題2)

然後比昨天還毒瘤的是今天連大樣例都沒了。

今天把聯考的排行榜粘過來以彰顯自己有多菜。

今天主要是時間分配掛了。

$T1$寫了三小時半多,$T2$用了$17min$,$T3$用了$10min$。然後瀏覽器被$oj$卡死提交用了$20min$。剩下時間在摸魚(放棄掙扎

$T1$最後會正解了但是來不及細想了(因爲$T2,3$暴力沒打)所以剩下$20$分不要就不要了。

考場上大規模幹$T1$就是腦子有問題。(大分類討論玩得挺歡?

$T2$寫了個亂搞本來能過$50$然後因爲分配的時間太少寫着急了有一個細節掛掉直接就爆零了。(我還以爲樣例不水)

全世界都沒幾個爆零的。。。

$T3$原題數學題。沒時間了所以打暴力跑路了。結果居然是全場$AC$數最多的題。。

什麼亂七八糟的。。。

 

T1:多邊形

大意:求正$n$邊形選$m$點構成的多邊形恰有$k$銳角的方案數。$n$是奇數。$n \le 10^6,T \le 10^5$

$k>3$無解。

考慮:多邊形外角和爲$360$。一個銳角對應一個$>90$的外角,故最多$3$個。

我們抽象一下問題:我們要選擇$m$個點$1 \le a_1 <a_2 < ... <a_m <n$。滿足恰有$k$個$i$滿足$a_{i+2}-a_i > \frac{n}{2}$

(序列是循環的,也就是$a_{m+1}=a_1,a+{m+3}=a_2$)

考慮爲什麼:首先作出原多邊形的外接圓,一個你選定的多邊形的角$ABC$也就是一個圓周角,則它對應的圓心角是二倍圓周角。

圓周角是銳角所以圓心角小於平角。所以說$a \rightarrow C$這一段弧是一個優弧,至少跨過$\frac{n}{2}$個點。

爲了方便下面設$N=\frac{n}{2}$

$k=3$時一定是三角形。此時$m \neq$則無解。

首先三角形的確可能有解。不是三角形的話則需要有三個$i$滿足條件,至少有兩個$i$的奇偶性相同。

$a_i < a_{i+2} < a_{i+2x} < a_{i+2x+2}$。第$1,3$個小於號的跨度都是$N$。所以$a_{i+2x+2}-a_i>n$就直接非法了。

然後一定是三角形的話,我們固定其中一個點,枚舉第二個點的編號,發現第三個點可選位置數是等差數列。直接$O(1)$解決。

$k=2$的話滿足條件的兩個$i$相差一定是$1$如果差距更大的話可以同上得到總長過長而非法。

我們欽定其中一個$i=1,a_1=1$。計算此時的方案再通過旋轉得到其它所有方案。

我們去枚舉$a_4$是幾。總方案是$\sum\limits_{a_4=N+3}^{n} \binom{n-a_4}{m-4} (a_4-N-2)^2$

就是後邊的點隨便選,那個平方就是在$a_1,a_4$之間選擇$a_2,a_3$的方案數。

考慮組合含義優化:我們在$[N+2,n]$裏選擇$a_4$,$n-a_4$個元需裏選$m-2$個,再在$a_4-N-2$個元素裏可重複選兩個。

分類討論你可重複選的那兩個是否重複了:

重複那就是一共在$[N+2,n]$裏隨便選$m-3$個然後欽定其中第二個是$a_4$。方案一一對應。直接組合數。

不重複那就多選一個,考慮到順序問題還要乘$2$。

特殊處理$m=3$。這樣$k=2$就可以$O(1)$解決。

$k=1$的話我採用的方法是:計數所有多邊形的銳角個數和再減去$k \ge 2$的方案的貢獻。

所以我們再次欽定一個銳角$i=1,a_1=1$。

這回只需要枚舉$a_3 > N+1$。方案數就是$\binom{n-a_3}{m-3} (a_3-2)$

還是組合含義優化,分類討論$a_2 >N+1$與否,組合數加上組合數乘係數。

$k=0$的情況就是所有情況減去上邊這些情況。

總時間複雜度$O(n+T)$

 1 #include<cstdio>
 2 const int mod=1000109107,S=1000005;
 3 int qp(int b,int t,int a=1){for(;t;t>>=1,b=1ll*b*b%mod)if(t&1)a=1ll*a*b%mod;return a;}
 4 int n,m,t,k,fac[S],inv[S];
 5 int C(int b,int t){return t<0||t>b?0:fac[b]*1ll*inv[t]%mod*inv[b-t]%mod;}
 6 int cal3(int n,int m){return m==3?n*(n+1ll)*(2*n+1)/6%mod:0;}
 7 int cal2(int n,int m){
 8     if(m==3)return (mod+C(n+n+1,3)-cal3(n,m))%mod;
 9     return (2ll*C(n,m-1)+C(n,m-2))*(1ll+n+n)%mod;
10 }
11 int cal1(int n,int m){
12     int ans=(C(n,m-2)*1ll*n+C(n,m-1))%mod;
13     return ((ans*(1ll+n+n)-2*cal2(n,m)%mod-3ll*cal3(n,m))%mod+mod)%mod;
14 }
15 int main(){
16     for(int i=fac[0]=1;i<S;++i)fac[i]=fac[i-1]*1ll*i%mod;
17     inv[S-1]=qp(fac[S-1],mod-2);
18     for(int i=S-2;~i;--i)inv[i]=inv[i+1]*(i+1ll)%mod;
19     scanf("%d",&t);while(t--){
20         scanf("%d%d%d",&n,&m,&k);
21         n>>=1;
22         if(k>3)puts("0");
23         else if(k==3)printf("%d\n",cal3(n,m));
24         else if(k==2)printf("%d\n",cal2(n,m));
25         else if(k==1)printf("%d\n",cal1(n,m));
26         else printf("%lld\n",(mod*3ll+C(n+n+1,m)-cal1(n,m)-cal2(n,m)-cal3(n,m))%mod);
27     }
28 }
View Code

 

T2:仙人掌

大意:樹,每次操作會使某個點所有鄰居權值$+1$並詢問所有鄰居權值異或和。$n,Q \le 5 \times 10^5$

每次$+1$的話那麼子樹裏所有節點的權值最多有$O(\sqrt{m})$種。

所以直接開一個$unordered-set$暴力維護子樹中所有點的權值及出現次數,複雜度$O(n\sqrt{n})$

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define f1 first
 4 #define s2 second
 5 const int mod=1000109107,S=1000005;
 6 int n,m,ans,fir[S],l[S],to[S],ec,f[S],ts[S],tf[S];
 7 unordered_map<int,int>M[S],R;
 8 void link(int a,int b){l[++ec]=fir[a];fir[a]=ec;to[ec]=b;}
 9 void dfs(int p,int fa){
10     f[p]=fa; M[fa][0]++;
11     for(int i=fir[p];i;i=l[i])if(to[i]!=fa)dfs(to[i],p);
12 }
13 int addson(int p){
14     int a=0;
15     for(auto x:M[p])R[x.f1+1]=x.s2,a^=x.s2&1?x.f1+1:0;
16     swap(M[p],R);R.clear(); return a;
17 }
18 int addfa(int p){
19     if(!p)return 0;
20     int a=tf[p]+ts[f[p]];
21     int&x=M[f[p]][a];x--; if(!x)M[f[p]].erase(M[f[p]].find(a));
22     M[f[p]][a+1]++; return a+1;
23 }
24 int main(){
25     scanf("%d%d",&n,&m);
26     for(int i=1,a,b;i<n;++i)scanf("%d%d",&a,&b),link(a,b),link(b,a);
27     dfs(1,0);
28     for(int _=1,x;_<=m;++_)
29         scanf("%d",&x),
30         ans=(ans+(1ll*_*_+_)%mod*(addson(x)^addfa(f[x])))%mod,
31         ts[x]++,tf[f[x]]++;
32     printf("%d\n",ans);
33 }
View Code

正解是,發現一個數$+1$相當與異或上$2^{z+1}-1$。$z$是最低的$0$位。

按從低位到高位維護$trie$表示兒子的所有權值。每次跑$1$方向修改並更新答案。$O(nlogn)$

 

T3:多項式

大意:有$n$個$0 <x\le T$的變量和$m$個$0<x$的變量,其和$\le S$。求方案數。$n \le 10^9,m \le 10^3,nT \le S \le 10^{18},T \le 10^9$

首先爲了方便去掉$\le S$的限制所以我們可以新增一個不限制的變量,也就是說$m++$。爲了讓它也滿足$x>0$需要讓$S++$

可以列出這樣一個基礎式子$\sum\limits_{x_{1...n},\sum a =x} \binom{S-x}{m}$

組合數化成下降冪除階乘,階乘可以拿出來單算。然後我們有

$n^{\underline{m}} = \sum\limits_{i=0}^{m} (-1)^{m-i} \begin{bmatrix} m \\ i\end{bmatrix} n^i$

也就有我們要求的是$\frac{1}{m!} \sum\limits_{\sum a_i = x} \sum\limits_{i=0}^{m} \begin{bmatrix} m \\ i \end{bmatrix}  (-1)^{m-i} (S-x)^i$

最後那個東西二項式展開一下

$\frac{1}{m!} \sum\limits_{\sum a_i = x} \sum\limits_{i=0}^{m} \begin{bmatrix} m \\ i \end{bmatrix}  (-1)^{m-i} \sum\limits_{j=0}^{i} S^{i-j}(-1)^j x^j$

這樣就只有最後一項與$x$有關了。我們要求的形如下式:

$A_j = \sum\limits_{\sum\limits_{i=1}^{n} a_i = x} x^j$

設$F_{k,j} = \sum\limits_{\sum\limits_{i=1}^{k} a_i = x} x^j$

根據二項式展開那一套,有$F_{x+y,i+j} = \sum F_{x,i} F(y,j) \binom{i+j}{i}$

所以可以直接倍增$F$求出$A$。$F_{0,i}$就是簡單的自然數冪和。隨便怎麼做都行。

式子逐層處理即可。時間複雜度$O(m^2logn)$

 1 #include<cstdio>
 2 #define ll long long
 3 const int mod=1000109107,S=1005;
 4 int n,m,t,fac[S],ans,F[31][S],A[S],st[S][S],St[S][S],C[S][S],iv[S],G[S],pws[S];ll s;
 5 int qp(int b,int t,int a=1){for(;t;t>>=1,b=1ll*b*b%mod)if(t&1)a=1ll*a*b%mod;return a;}
 6 int Spw(int n,int k,int a=0){for(int i=0,C=1+n;i<=k;++i)a=(a+1ll*St[k][i]*fac[i]%mod*C)%mod,C=1ll*C*(n-i)%mod*iv[i+2]%mod;return a;}
 7 int main(){
 8     for(int i=fac[0]=iv[1]=1;i<S;++i)fac[i]=fac[i-1]*1ll*i%mod;
 9     for(int i=2;i<S;++i)iv[i]=mod-mod/i*1ll*iv[mod%i]%mod;
10     for(int i=st[0][0]=St[0][0]=C[0][0]=1;i<S;++i)for(int j=C[i][0]=1;j<=i;++j)
11         st[i][j]=(st[i-1][j]*(i-1ll)+st[i-1][j-1])%mod,
12         St[i][j]=(St[i-1][j]*1ll*j+St[i-1][j-1])%mod,
13         C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
14     scanf("%lld%d%d%d",&s,&t,&n,&m); m-=n; s%=mod;
15     for(int i=0;i<=m;++i)F[0][i]=Spw(t,i); F[0][0]--;
16     for(int i=1;1<<i<=n;++i)for(int j=0;j<=m;++j)for(int k=0;k+j<=m;++k)
17         F[i][j+k]=(F[i][j+k]+1ll*F[i-1][j]*F[i-1][k]%mod*C[j+k][j])%mod;
18     for(int i=0;i<=30;++i)F[i][0]--;
19     A[0]=1;
20     for(int i=0;1<<i<=n;++i)if(n>>i&1)for(int j=m;~j;--j)for(int k=m-j;~k;--k)
21         A[j+k]=(A[j+k]+1ll*A[j]*F[i][k]%mod*C[j+k][j])%mod;
22     for(int i=pws[0]=1;i<=m;++i)pws[i]=pws[i-1]*1ll*s%mod;
23     for(int i=0;i<=m;++i)for(int j=0;j<=i;++j)
24         G[i]=(G[i]+(j&1?mod-1ll:1ll)*pws[i-j]%mod*A[j]%mod*C[i][j])%mod;
25     for(int i=0;i<=m;++i)ans=(ans+(m-i&1?mod-1ll:1ll)*st[m][i]%mod*G[i])%mod;
26     printf("%lld\n",ans*1ll*qp(fac[m],mod-2)%mod);
27 }
View Code

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章