20180618小测

为什么今天还考试啊......

T1:


一眼不可做。
想维护分组状态,用最小表示法,总共8个集合,状态量400+,不可做。
弃疗写了20分的puts。
正解是容斥。
我们设f[i][j][k]为考虑i位,j个串,k个与输入串的前缀不完全相同,xor为0,数字可重复,考虑顺序的方案数,显然我们能把它扔进一个n*n的矩阵里转移。
然后我们令g[i]为考虑输入串全部,i个串,xor为0,数字不可重复,不考虑顺序的方案数。显然不考虑顺序不好做,我们先计算考虑顺序的,最后再除以阶乘。
考虑顺序的怎么算?我们考虑容斥。假设g[0,i-1]已经求出。我们考虑这i个串中有j个本质不同的串,显然j=i-2k,因为重复串必须出现两次。
然后我们枚举这i个串有多少出现在j个串中,多于剩下的串,假设有2p个,那么我们相当于是要在剩下的R-j个串中找p个可重复的串了。
怎么做?dfs一下,然后组合数+可重集排列就好。
然而细节还是不少的。
考场20分代码:

1 #include<cstdio>
2 using namespace std;
3 
4 int main() {
5     static int n;
6     scanf("%d",&n);
7     if( n <= 2 ) return printf("%d\n",2-n) , 0;
8     return 0;
9 }
View Code

正解代码:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #define debug cout
  6 typedef long long int lli;
  7 using namespace std;
  8 const int maxn=8,maxm=5e6+1e2;
  9 const int mod=1e9+7;
 10 
 11 inline int add(const int &x,const int &y) {
 12     const int ret = x + y;
 13     return ret >= mod ? ret - mod : ret;
 14 }
 15 inline int sub(const int &x,const int &y) {
 16     const int ret = x - y;
 17     return ret < 0 ? ret + mod : ret;
 18 }
 19 inline int mul(const int &x,const int &y) {
 20     return (lli) x * y % mod;
 21 }
 22 inline void adde(int &dst,const int &x) {
 23     if( ( dst += x ) >= mod ) dst -= mod;
 24 }
 25 inline void sube(int &dst,const int &x) {
 26     if( ( dst -= x ) < 0 ) dst += mod;
 27 }
 28 inline void mule(int &dst,const int &x) {
 29     dst = (lli) dst * x % mod;
 30 }
 31 inline int fastpow(int base,int tim) {
 32     int ret = 1;
 33     while(tim) {
 34         if( tim & 1 ) mule(ret,base);
 35         if( tim >>= 1 ) mule(base,base);
 36     }
 37     return ret;
 38 }
 39 
 40 char in[maxm];
 41 int n,m,k,t,R;
 42 struct Matrix { // dat[1][i] means i number all same with R .
 43     int dat[maxn][maxn];
 44     Matrix(int tpe=0) {
 45         memset(dat,0,sizeof(dat));
 46         for(int i=0;i<=n;i++) dat[i][i] = tpe;
 47     }
 48     int* operator [] (const int &x) { return dat[x]; }
 49     const int* operator [] (const int &x) const { return dat[x]; }
 50     friend Matrix operator * (const Matrix &a,const Matrix &b) {
 51         Matrix ret;
 52         for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) for(int k=0;k<=n;k++) adde(ret[i][j],mul(a[i][k],b[k][j]));
 53         return ret;
 54     }
 55     friend Matrix operator + (const Matrix &a,const Matrix &b) {
 56         Matrix ret;
 57         for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) ret[i][j] = add(a[i][j],b[i][j]);
 58         return ret;
 59     }
 60 }trans[maxn][2],f[maxn];
 61 int g[maxn],fac[maxn],inv[maxn],lam[maxn][maxn],sel[maxn<<1];
 62 int tab[1<<7];
 63 
 64 inline int countbit(int x) {
 65     return tab[x];
 66 }
 67 inline int c(int n,int m) {
 68     return mul(fac[n],mul(inv[m],inv[n-m]));
 69 }
 70 inline void getrans(int n) {
 71     // get trans 0 .
 72     for(int same=0;same<=n;same++) {
 73         const int different = n - same;
 74         for(int different_select=0;different_select<=different;different_select++)
 75             if( ! ( different_select & 1 ) ) {
 76                 adde(trans[n][0][same][same],c(different,different_select));
 77             }
 78     }
 79     // get trans 1 .
 80     for(int same=0;same<=n;same++) {
 81         const int different = n - same;
 82         for(int same_select=0;same_select<=same;same_select++)
 83             for(int different_select=0;different_select<=different;different_select++)
 84                 if( ! ( ( same_select + different_select ) & 1 ) ) {
 85                     adde(trans[n][1][same][same_select],mul(c(same,same_select),c(different,different_select)));
 86                 }
 87     }
 88 }
 89 
 90 inline Matrix fastpow(Matrix base,int tim) {
 91     Matrix ret(1);
 92     while(tim) {
 93         if( tim & 1 ) ret = ret * base;
 94         if( tim >>= 1 ) base = base * base;
 95     }
 96     return ret;
 97 }
 98 inline void getans() {
 99     for(int i=1;i<=n;i++) f[i][0][i] = 1;
100     for(int j=1;j<=n;j++) {
101         Matrix cur(1);
102         for(int i=1;i<=t;i++) cur = cur * trans[j][(int)in[i]-'0'];
103         f[j] = f[j] * fastpow(cur,m/t);
104     }
105     g[0] = 1;
106     for(int i=1;i<=n;i++) g[i] = f[i][0][0];
107     for(int i=1;i<=n;i++) if( ( i & 1 ) == ( n & 1 ) ) {
108         for(int j=i&1;j<i;j+=2) sube(g[i],mul(g[j],lam[i][j]));
109         mule(g[i],inv[i]);
110     }
111 }
112 
113 inline int getpir(int used,int ned) {
114     int base = sub(R,used) , ret = 1;
115     for(int i=1;i<=ned;i++) mule(ret,base) , sube(base,1);
116     return mul(ret,inv[ned]);
117 }
118 inline void calc(int pos,int fs,int su) {
119     if( pos < fs ) return;
120     int ret = mul(getpir(fs,pos-fs-1),fac[su]);
121     for(int i=1;i<pos;i++) mule(ret,inv[sel[i]]);
122     adde(lam[su][fs],ret);
123 }
124 inline void dfs_lam(int pos,int rem,int fs,int su) {
125     if(!rem) return calc(pos,fs,su);
126     for(int i=1+(pos>fs);i<=rem;i+=2) sel[pos] = i , dfs_lam(pos+1,rem-i,fs,su);
127 }
128 
129 inline void pre_lam() {
130     *fac = 1;
131     for(int i=1;i<=n;i++) fac[i] = mul(fac[i-1],i);
132     inv[n] = fastpow(fac[n],mod-2);
133     for(int i=n;i;i--) inv[i-1] = mul(inv[i],i);
134     for(int i=1;i<=m;i++) adde(R,R) , adde(R,in[i]-'0');
135     for(int i=1;i<=n;i++) if( ( i & 1 ) == ( n & 1 ) ) for(int j=i&1;j<i;j+=2) dfs_lam(1,i,j,i);
136 }
137 
138 int main() {
139     scanf("%d%d%s",&n,&k,in+1) , t = m = strlen(in+1);
140     for(int i=1;i<1<<n;i++) tab[i] = tab[i>>1] + (i&1);
141     for(int j=1;j<=m;j++) for(int i=1;i<k;i++) in[i*m+j] = in[j];
142     m *= k , pre_lam();
143     for(int i=1;i<=n;i++) if( ( i & 1 ) == ( n & 1 ) ) getrans(i);
144     getans() , printf("%d\n",g[n]);
145     return 0;
146 }
View Code

 


T2:


40分暴力直接一个大力枚举+bitset即可。
正解的话,只需要考虑c=2或者c=3的情况,然后莫比乌斯反演。
咕咕咕了。
考场40分代码:

 1 #include<cstdio>
 2 #include<bitset>
 3 #include<cmath>
 4 typedef long long int lli;
 5 using namespace std;
 6 const int maxn=1e9+1e2;
 7 
 8 bitset<maxn> vis;
 9 
10 inline int calc(int lim) {
11     vis &= 0;
12     for(int i=1;i<=1000;i++)
13         for(int j=i+1,sq=sqrt(lim/i);j<=sq;j++)
14             for(lli k=j*j;i*k<=lim;k*=j) vis[i*k] = 1;
15     return vis.count();
16 }
17 
18 int main() {
19     static int l,r;
20     scanf("%d%d",&l,&r) , printf("%d\n",calc(r)-calc(l-1));
21     return 0;
22 }
View Code

 


T3:


题意就是,我们求出每种点数的方案数,然后把它摊开,求方差。
只会20分dfs。
正解是一个O(n^4)的大力分类讨论+容斥+DP,具(我)体(也)做(是)法(抄)不(的)写(题)了(解)。
考场20分代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define debug cout
 6 typedef long long int lli;
 7 using namespace std;
 8 const int maxn=(1<<20)+7,maxt=50;
 9 const int mod=998244353;
10 const int dx[]={-1,1,0,0},dy[]={0,0,-1,1};
11 
12 inline int sub(const int &a,const int &b) {
13     const int ret = a - b;
14     return ret < 0 ? ret + mod : ret;
15 }
16 inline int mul(const int &a,const int &b) {
17     return (lli) a * b % mod;
18 }
19 inline void adde(int &dst,const int &x) {
20     if( ( dst += x ) >= mod ) dst -= mod;
21 }
22 inline void mule(int &dst,const int &x) {
23     dst = (lli) dst * x % mod;
24 }
25 inline int sq(const int &x) {
26     return mul(x,x);
27 }
28 
29 inline int fastpow(int base,int tim) {
30     int ret = 1;
31     while(tim) {
32         if( tim & 1 ) mule(ret,base);
33         if( tim >>= 1 ) mule(base,base);
34     }
35     return ret;
36 }
37 
38 int vis[maxt][maxt];
39 int v[maxn],e[maxn],cnt;
40 int in[4],fs,n;
41 
42 inline void dfs(int dep,int x,int y,int val,int ex) {
43     if( dep > n ) {
44         v[++cnt] = val , e[cnt] = ex;
45         return;
46     }
47     ++vis[x][y];
48     for(int i=0;i<4;i++) {
49         const int tx = x + dx[i] , ty = y + dy[i];
50         dfs(dep+1,tx,ty,val+!vis[tx][ty],mul(ex,in[i]));
51     }
52     --vis[x][y];
53 }
54 
55 inline int calc() {
56     int avr = 0 , su = 0 , ws = 0;
57     for(int i=1;i<=cnt;i++) adde(avr,mul(v[i],e[i])) , adde(ws,e[i]);
58     mule(avr,fastpow(ws,mod-2));
59     for(int i=1;i<=cnt;i++) adde(su,mul(e[i],sq(sub(avr,v[i]))));
60     return mul(su,fastpow(fs,n));
61 }
62 
63 int main() {
64     scanf("%d",&n);
65     for(int i=0;i<4;i++) scanf("%d",in+i) , adde(fs,in[i]);
66     dfs(1,n,n,1,1) , printf("%d\n",calc());
67     return 0;
68 }
View Code

正解代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define Fixy for(int i=1;i<=n;i++) for(int x=-n;x<=n;x++) for(int y=-n;y<=n;y++)
 6 #define debug cout
 7 typedef long long int lli;
 8 using namespace std;
 9 const int maxn=2e2+1e1;
10 const int mod=998244353;
11 const int dx[]={-1,1,0,0},dy[]={0,0,-1,1};
12 
13 inline int sub(const int &x,const int &y) {
14     const int ret = x - y;
15     return ret < 0 ? ret + mod : ret;
16 }
17 inline int mul(const int &x,const int &y) {
18     return (lli) x * y % mod;
19 }
20 inline void adde(int &dst,const int &x) {
21     if( ( dst += x ) >= mod ) dst -= mod;
22 }
23 inline void sube(int &dst,const int &x) {
24     if( ( dst -= x ) < 0 ) dst += mod;
25 }
26 inline void mule(int &dst,const int &x) {
27     dst = (lli) dst * x % mod;
28 }
29 inline int fastpow(int base,int tim) {
30     int ret = 1;
31     while(tim) {
32         if( tim & 1 ) mule(ret,base);
33         if( tim >>= 1 ) mule(base,base);
34     }
35     return ret;
36 }
37 
38 int in[4],su,n;
39 int g[maxn],sumw[maxn],sumf[maxn];
40 struct Array {
41     int dat[maxn>>1][maxn][maxn];
42     inline int& operator () (const int &i,const int &x,const int &y) {
43         return dat[i][x+n+1][y+n+1];
44     }
45 }w,r,s,f;
46 
47 inline int judge(const int &x,const int &y) {
48     return -n <= x && x <= n && -n <= y && y <= n;
49 }
50 inline void getw() {
51     w(0,0,0) = 1;
52     for(int i=0;i<n;i++) for(int x=-n;x<=n;x++) for(int y=-n;y<=n;y++) if( w(i,x,y) ) for(int j=0;j<4;j++) {
53         const int tx = x + dx[j] , ty = y + dy[j];
54         if( judge(tx,ty) ) adde(w(i+1,tx,ty),mul(w(i,x,y),in[j]));
55     }
56 }
57 inline void getg() {
58     int pi = 1; g[0] = 1;
59     for(int i=1;i<=n;i++) {
60         mule(pi,su) , g[i] = pi;
61         for(int j=1;j<=i;j++) sube(g[i],mul(w(j,0,0),g[i-j]));
62     }
63 }
64 inline void getr() {
65     Fixy {
66         r(i,x,y) = w(i,x,y);
67         for(int j=1;j<i;j++) sube(r(i,x,y),mul(w(j,0,0),r(i-j,x,y)));
68     }
69 }
70 inline void gets() {
71     Fixy {
72         for(int j=1;j<i;j++) adde(s(i,x,y),mul(w(j,x,y),r(i-j,-x,-y)));
73     }
74 }
75 inline void getf() {
76     Fixy if( x || y ) {
77         for(int j=1;j<=i;j++) adde(f(i,x,y),mul(g[i-j],w(j,x,y)));
78         for(int j=1;j<=i;j++) sube(f(i,x,y),mul(g[i-j],s(j,x,y)));
79         for(int j=1;j<=i;j++) sube(f(i,x,y),mul(f(i-j,x,y),sub(w(j,0,0),s(j,-x,-y))));
80     }
81 }
82 inline int getans() {
83     static int d,d2;
84     for(int i=0;i<=n;i++) for(int x=-n;x<=n;x++) for(int y=-n;y<=n;y++) adde(sumf[i],f(i,x,y));
85     for(int i=0;i<=n;i++) for(int x=-n;x<=n;x++) for(int y=-n;y<=n;y++) adde(sumw[i],w(i,x,y));
86     for(int i=0;i<=n;i++) adde(d,mul(sumw[i],g[n-i]));
87     for(int i=0;i<=n;i++) adde(d2,mul(sumf[i],sumw[n-i]));
88     adde(d2,d2) , adde(d2,d) , mule(d2,fastpow(su,n));
89     return sub(d2,mul(d,d));
90 }
91 
92 
93 int main() {
94     scanf("%d",&n);
95     for(int i=0;i<4;i++) scanf("%d",in+i) , adde(su,in[i]);
96     getw() , getg() , getr() , gets() , getf() , printf("%d\n",getans());
97     return 0;
98 }
View Code

 


为什么这种容斥都不会啊......我菜爆了,还是退役吧!
对我而言的话,大概死亡也是一种救赎吧。(rm -rf ME)

冷た過ぎて 凍える夜も
在冷清凄惨之夜
もう 寂しくはないね
也不再感到寂寞
君といれたら 流れる星も
立于君旁 闪过的流星
綺麗に見えるんだ
看起来都那么绮丽
キラリ キラリ 瞬く星を
与你一起数过的
君と何度も数えたら
一闪一闪的漫天繁星
ひとつ ふたつ つながる絆
都结成我们的羁绊

posted @ 2018-06-18 21:52  Cmd2001  阅读(285)  评论(0编辑  收藏  举报