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> 5View Code#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(constint &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 }
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)
冷た過ぎて 凍える夜も
在冷清淒慘之夜
もう 寂しくはないね
也不再感到寂寞
君といれたら 流れる星も
立於君旁 閃過的流星
綺麗に見えるんだ
看起來都那麽綺麗
キラリ キラリ 瞬く星を
與你一起數過的
君と何度も數えたら
一閃一閃的漫天繁星
ひとつ ふたつ つながる絆
都結成我們的羈絆
20180618小測