省选前作业题汇总1

(部分是)2019.2.27交流题,题目顺序瞎排的

codeM2017初赛B轮D题

这为啥会放进省选作业里啊=。=

这不就是问你$gcd(a,k-1) equiv c(mod$ $b)$有没有解吗,裴蜀定理,没了  

代码不放了

CF724E Goods transportation

咦,这不是wxx以前交流的时候讲的题吗=。=

WF2012 infiltration

乱搞题,主要是要发现答案不超过log,然后1-5暴力判,其余输出6

代码不放了

CF547D Mike and fish

每条鱼的行列对应连边,构成一张二分图。这个题说明了:给一张二分图边黑白染色,使得每个节点的黑白边数相差不超过1,是一定可行的。原因大概是(口胡)二分图里没有奇环,所以DFS涂色,要么是交替涂了一个偶环,每个点的黑白边差不变;要么涂了一条链,只有端点变化了1,只要在下次它又做端点时涂另一种颜色即可。

具体实现差不多,先涂奇节点,然后直接涂,看代码吧

 1 #include<set>
 2 #include<map>
 3 #include<cstdio>
 4 #include<cstring> 
 5 #include<algorithm>
 6 #define pii pair<int,int>
 7 using namespace std;
 8 const int N=400005,M=2e5;
 9 int n,x[N],y[N];
10 set<int> p[N]; 
11 map<pii,int> r;
12 void DFS(int nde)
13 {
14     if(p[nde].empty()) return;
15     int nxt=*p[nde].begin();
16     p[nde].erase(nxt),p[nxt].erase(nde);
17     r[make_pair(nde,nxt)]=true; DFS(nxt);
18 }
19 int main()
20 {
21     scanf("%d",&n);
22     for(int i=1;i<=n;i++)
23     {
24         scanf("%d%d",&x[i],&y[i]);
25         p[x[i]].insert(y[i]+M);
26         p[y[i]+M].insert(x[i]);
27     }
28     for(int i=1;i<=2*M;i++)
29         if(p[i].size()%2) DFS(i);
30     for(int i=1;i<=2*M;i++)
31         while(!p[i].empty()) DFS(i);
32     for(int i=1;i<=n;i++)
33         r[make_pair(x[i],y[i]+M)]?putchar('r'):putchar('b');
34     return 0;
35 }
View Code

NOI 2017 泳池

吉如一的神仙题

先说式子怎么推的

zlk:dp不出来的,后容斥一下就能dp了

等于不好求,我们求小于等于然后作差

设$dp[i][j]$表示一个宽$i$高$j$的矩形,其中$j-1$行及以下全部安全,第$j$行存在不安全区域,整个矩形里的全部安全的子矩形大小不超过$k$的概率。转移是枚举第一个不安全的那个区域在哪,这里设安全的概率是$p$,那么有

$dp[i][j]=p^{j-1}(1-p) sumlimits_{k=1}^i(sum_{h>j}dp[k-1][h])(sum_{h>=j}dp[i-k][h]) (i*(j-1)<=k)$

用后缀和优化一下就可以$O(k^2)$求出来了,然后再求我们的答案$ans$。设$ans[i]$表示宽为$i$时的答案,在最底下一行枚举拼合点前后拼起来,再加上整段的情况

$ans[i]=dp[i][2]+sumlimits_{j=1}^n ans[i-j]*dp[j-1][2]*(1-p)$

我们终于得到了一个$O(nk)$的做法,可喜可贺,可喜可贺

好啊,矩阵乘法!再一看k=1000......

这个求ans的过程是一个常系数线性递推,为了避免这篇题目汇总过长,我把常系数线性递推单独开个模板写,这里只需要$O(k^2)$多项式取模的方法就可以通过了。算上快速幂总复杂度$O(k^2log n)$

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=1005,mod=998244353;
 6 int m,k,x,y,p,pp,dp[N],pw[N],mo[N],mu[N],cal[2*N],ret[N],f[N][N];
 7 void Add(int &x,int y)
 8 {
 9     x+=y;
10     if(x>=mod) x-=mod;
11 }
12 int Qpow(int x,int k)
13 {
14     if(k==1) return x;
15     int tmp=Qpow(x,k/2);
16     return k%2?1ll*tmp*tmp%mod*x%mod:1ll*tmp*tmp%mod;
17 }
18 void Polymul(int *a,int *b,int *m,int *r,int len)
19 {
20     for(int i=0;i<=len;i++)
21         for(int j=0;j<=len;j++)
22             Add(cal[i+j],1ll*a[i]*b[j]%mod);
23     for(int i=2*len;i>=len;i--)
24         if(cal[i]) 
25             for(int j=0;j<=len;j++)
26                 Add(cal[i+j-len],mod-1ll*cal[i]*m[j]%mod);
27     for(int i=0;i<=len;i++) r[i]=cal[i],cal[i]=0;
28 }
29 int Solve(int n)
30 {
31     for(int i=1;i<=n+2;i++) f[0][i]=1;
32     for(int i=1;i<=n;i++)
33     {
34         for(int j=2;i*(j-1)<=n;j++)
35         {
36             int tmp=0;
37             for(int h=1;h<=i;h++)
38                 Add(tmp,1ll*f[h-1][j+1]*f[i-h][j]%mod);
39             f[i][j]=1ll*tmp*pw[j-1]%mod*pp%mod;
40         }
41         f[i][n/i+2]=0;
42         for(int j=n/i+1;j>=2;j--)
43             Add(f[i][j],f[i][j+1]);
44     }
45 //    for(int i=0;i<=n;i++,puts(""))
46 //        for(int j=0;j<=n;j++)
47 //            printf("%d ",f[i][j]);
48     memset(dp,0,sizeof dp),dp[0]=1;
49     for(int i=1;i<=n;i++)
50     {
51         for(int j=1;j<=i;j++)
52             Add(dp[i],1ll*dp[i-j]*f[j-1][2]%mod*pp%mod);
53         Add(dp[i],f[i][2]);
54     }
55     for(int i=0;i<=n;i++) 
56         mo[i]=1ll*(mod-f[n-i][2])*pp%mod; mo[++n]=1;
57 //    for(int i=0;i<=n;i++) printf("%d ",mo[i]);puts("");
58     memset(mu,0,sizeof mu),memset(ret,0,sizeof ret);
59     mu[1]=1,ret[0]=1; int ept=m,ans=0; 
60     while(ept)
61     {
62         if(ept&1) Polymul(ret,mu,mo,ret,n);
63         Polymul(mu,mu,mo,mu,n),ept>>=1;
64     }//for(int i=0;i<=n;i++) printf("%d ",ret[i]);puts("");
65     for(int i=0;i<n;i++)
66         Add(ans,1ll*dp[i]*ret[i]%mod);
67     return ans;
68 }
69 int main()
70 {
71     scanf("%d%d%d%d",&m,&k,&x,&y);
72     p=1ll*x*Qpow(y,mod-2)%mod;
73     pp=(1-p+mod)%mod,pw[0]=1;
74     for(int i=1;i<=k;i++) 
75         pw[i]=1ll*pw[i-1]*p%mod;
76     printf("%d",(Solve(k)-Solve(k-1)+mod)%mod);
77     return 0;
78 }
View Code

SDOI 2016 储能表

居然是数位DP,惊了

$dp[b][0/1][0/1][0/1][2]$表示第$b$位时是否碰到n/m/k的上界......的方案数和异或和

指针看着真难受,可读性--;但是用高维数组又长又慢,就凑活着吧=。=

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define ll long long
 5 using namespace std;
 6 ll T,n,m,k,mod,dp[72][2][2][2][3];
 7 void Add(ll &x,ll y)
 8 {
 9     x+=y;
10     if(x>=mod) x-=mod;
11 }
12 void i207M()
13 {
14     scanf("%lld%lld%lld%lld",&n,&m,&k,&mod);
15     memset(dp,0,sizeof dp),n--,m--; 
16 }
17 void DFS(int bit,int rn,int rm,int rk)
18 {
19     ll *pt=dp[bit][rn][rm][rk];
20     if(bit==63) *pt=1;
21     else
22     {
23         if(*(pt+2)) return;
24         int bt=62-bit,np=(n>>bt)&1,mp=(m>>bt)&1,kp=(k>>bt)&1;
25         int lim1=rn?np:1,lim2=rm?mp:1;
26         for(int i=0;i<=lim1;i++)
27             for(int j=0;j<=lim2;j++)
28                 if(!rk||((i^j)>=kp))
29                 {
30                     int nb=bit+1,nn=rn&&(i==np),nm=rm&&(j==mp),nk=rk&&((i^j)==kp);
31                     DFS(nb,nn,nm,nk); ll b=(1ll<<(62-bit))%mod,*pts=dp[nb][nn][nm][nk];
32                     Add(*pt,*pts),Add(*(pt+1),((i^j)*b* *pts%mod+*(pts+1))%mod);
33                 }
34         *(pt+2)=true;
35     }
36     return;
37 }
38 int main()
39 {
40     scanf("%lld",&T);
41     while(T--)
42     {
43         i207M(),DFS(1,1,1,1); ll *pt=dp[1][1][1][1]; 
44         printf("%lld
",(*(pt+1)-k%mod* *pt%mod+mod)%mod);
45     }
46     return 0;
47 }
View Code

滑稽树下滑稽果

咕咕咕

量子态的棋盘

咕咕咕

CF848E 

咕咕咕

原文地址:https://www.cnblogs.com/ydnhaha/p/10442454.html