1. 程式人生 > 實用技巧 >Centos7 部署GlusterFS

Centos7 部署GlusterFS

T1001Road To The 3rd Building

總的方案數有 n(n+2)/2 種。然後考慮每種方案的貢獻:

設s[i]為字首和,Ans是總的貢獻,ans[i]是中間過程的累加和。

ans[i] = s[n-i+1] - s[i-1] + ans[i-1]

Ans= $\sum_{i=1}^n$ ans[i]/i

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int mod= 1e9+7;
 5 const int N=2e5+10;
 6 ll s[N];
7 ll ans[N]; 8 ll quick_pow(ll x,ll y){ 9 ll res=1; 10 while(y){ 11 if(y&1) res=res*x%mod; 12 x=x*x%mod; 13 y>>=1; 14 } 15 return res; 16 } 17 int main() 18 { 19 int T; 20 scanf("%d",&T); 21 while(T--){ 22 ll Ans=0; 23 ll n;
24 scanf("%lld",&n); 25 for(int i=1;i<=n;i++){ 26 scanf("%lld",&s[i]); 27 s[i]=(s[i]+s[i-1])%mod; 28 } 29 for(int i=1;i<=n;i++){ 30 ans[i]=(s[n-i+1]-s[i-1]+ans[i-1]+mod)%mod; 31 ll inv=quick_pow(i,mod-2); 32
Ans=(Ans+ans[i]*inv%mod)%mod; 33 } 34 ll inv=quick_pow(n*(n+1)%mod,mod-2); 35 Ans=(Ans*2%mod*inv)%mod; 36 printf("%lld\n",Ans); 37 } 38 return 0; 39 }

T1002Little Rabbit's Equation

先找出方程最小可能是幾進位制(通過方程中的數字、字母判斷),然後從 最小可能的進位制 到16進位制迴圈模擬,找到符合方程的最小進位制。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 char s[30];
 5 int main()
 6 {
 7     while(~scanf("%s",s+1)){
 8         int len=strlen(s+1);
 9         int mx=2;
10         for(int i=1;i<=len;i++){
11             if(s[i]>='0'&&s[i]<='9')
12                 mx=max(mx,s[i]-48+1);
13             if(s[i]>='A'&&s[i]<='F')
14                 mx=max(mx,s[i]-'A'+10+1);
15         }
16         bool flag=0;
17         for(ll k=mx;k<=16;k++){
18             ll x=0,y=0,z=0;
19             int i=1,j;
20             while(s[i]!='+'&&s[i]!='-'&&s[i]!='*'&&s[i]!='/'){
21                 if(s[i]>='A'){
22                     x=x*k+s[i]-'A'+10;
23                 }
24                 else x=x*k+s[i]-48;
25                 i++;
26             }
27             if(s[i]=='+') j=1;
28             else if(s[i]=='-') j=2;
29             else if(s[i]=='*') j=3;
30             else j=4;
31             i++;
32             while(s[i]!='='){
33                 if(s[i]>='A'){
34                     y=y*k+s[i]-'A'+10;
35                 }
36                 else y=y*k+s[i]-48;
37                 i++;
38             }
39             i++;
40             while(i<=len){
41                 if(s[i]>='A'){
42                     z=z*k+s[i]-'A'+10;
43                 }
44                 else z=z*k+s[i]-48;
45                 i++;
46             }
47             //printf("%lld %lld %lld\n",x,y,z);
48             if(j==1&&x+y==z){
49                 flag=1;
50                 printf("%lld\n",k);
51                 break;
52             }
53             if(j==2&&x-y==z){
54                 flag=1;
55                 printf("%lld\n",k);
56                 break;
57             }
58             if(j==3&&x*y==z){
59                 flag=1;
60                 printf("%lld\n",k);
61                 break;
62             }
63             if(j==4&&x==y*z){
64                 flag=1;
65                 printf("%lld\n",k);
66                 break;
67             }
68         }
69         if(flag==0) printf("-1\n");
70     }
71     return 0;
72 }

T1005Fragrant numbers

區間dp,通過觀察,只需要前13個數便可代表所有的數來構造前5000個數(當然,數不一定全部構造出來)。

dp[ i ][ j ][ k ] 表示 i - j 區間能否構造出k。

對於每個詢問,只需要找到dp[ 1 ][ i ][ n ] = 1 的最小的右端點 i 。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=5010;
 5 const int a[13]={1,1,4,5,1,4,1,9,1,9,1,1,4};
 6 bool dp[20][20][N];
 7 int ans[N];
 8 int getnum(int l,int r){
 9     int num=0;
10     for(int i=l;i<=r;i++)
11         num=num*10+a[i-1];
12     return num;
13 }
14 void Prepare(){
15     for(int i=1;i<=13;i++){
16         dp[i][i][a[i-1]]=1;
17     }
18     for(int len=1;len<13;len++){
19         for(int i=1;i+len<=13;i++){
20             int j=i+len;
21             if(len<4){
22                 int x=getnum(i,j);
23                 if(x<=5000) dp[i][j][x]=1;
24             }
25             for(int k=i;k<j;k++){
26                 for(int u=1;u<=5000;u++){
27                     if(dp[i][k][u]==0) continue;
28                     for(int v=1;v<=5000;v++){
29                         if(dp[k+1][j][v]==0) continue;
30                         if(u+v<=5000) dp[i][j][u+v]=1;
31                         if(u*v<=5000) dp[i][j][u*v]=1;
32                         if(u+v>5000&&u*v>5000) break;
33                     }
34                 }
35             }
36         }
37     }
38     memset(ans,-1,sizeof(ans));
39     for(int i=13;i>=1;i--)
40         for(int j=1;j<=5000;j++)
41             if(dp[1][i][j])
42                 ans[j]=i;
43 }
44 int main()
45 {
46     Prepare();
47     int T;
48     scanf("%d",&T);
49     while(T--){
50         int n;
51         scanf("%d",&n);
52         printf("%d\n",ans[n]);
53     }
54     return 0;
55 }

T1006A Very Easy Graph Problem

有一個明顯的結論 $\sum_{i=1}^n$ $2^i$ < $2^{n+1}$

所以可以從第一條邊開始建立最小生成樹,因為根據以上結論,每兩個點之間的最短路經過的邊一定在最小生成樹上。

這樣可以統計最小生成樹上每條邊的貢獻(經過的次數*邊長)。我的方法是直接兩次dfs,第一次統計子樹中0和1的個數,第二次計算貢獻。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int mod=1e9+7;
 5 const int N=1e5+10;
 6 const int M=2e5+10;
 7 int head[N],to[M],nxt[M];
 8 ll w[M];
 9 int tot;
10 int n,m;
11 int a[N];
12 int s[N];
13 ll num0[N],num1[N];
14 ll ans;
15 void init(){
16     tot=0;
17     ans=0;
18     memset(head,0,sizeof(head));
19 }
20 int find_set(int x){
21     if(x!=s[x]) return s[x]=find_set(s[x]);
22     return s[x];
23 }
24 inline void add(int u,int v,ll x){
25     to[++tot]=v,nxt[tot]=head[u],w[tot]=x,head[u]=tot;
26 }
27 void dfs(int u,int fa){
28     if(a[u]==0) num0[u]=1,num1[u]=0;
29     else num1[u]=1,num0[u]=0;
30     for(int i=head[u];i;i=nxt[i]){
31         int v=to[i];
32         if(v==fa) continue;
33         dfs(v,u);
34         num0[u]+=num0[v];
35         num1[u]+=num1[v];
36     }
37 }
38 void dfs2(int u,int fa){
39     for(int i=head[u];i;i=nxt[i]){
40         int v=to[i];
41         if(v==fa) continue;
42         ans=(ans+(num0[v]*(num1[1]-num1[v]+mod)%mod+num1[v]*(num0[1]-num0[v]+mod)%mod)*w[i]%mod)%mod;
43         dfs2(v,u);
44     }
45 }
46 int main()
47 {
48     int T;
49     scanf("%d",&T);
50     while(T--){
51         init();
52         scanf("%d%d",&n,&m);
53         for(int i=1;i<=n;i++){
54             scanf("%d",&a[i]);
55             s[i]=i;
56         }
57         ll val=1;
58         for(int i=1;i<=m;i++){
59             int u,v;
60             scanf("%d%d",&u,&v);
61             val=val*2%mod;
62             int x=find_set(u),y=find_set(v);
63             if(x!=y){
64                 s[y]=x;
65                 add(u,v,val);
66                 add(v,u,val);
67             } 
68         }
69         dfs(1,0);
70         dfs2(1,0);
71         printf("%lld\n",ans);
72     }
73     return 0;
74 }

T1009Divisibility

在b進位制下,一個數被x整除的充要條件是所有位上的數加起來可以被x整除,則(b-1)是x的倍數。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int mod= 998244353;
 5 
 6 int main()
 7 {
 8     int T;
 9     scanf("%d",&T);
10     while(T--){
11         ll b,x;
12         scanf("%lld%lld",&b,&x);
13         if((b-1)%x==0){
14             printf("T\n");
15         }
16         else printf("F\n");
17     }
18     return 0;
19 }

T1010Expectation

先用矩陣樹定理求出所有生成樹的個數。

然後進行二進位制拆位。即對於邊權的每一位,找出邊權的那一位為1的所有邊,再次用矩陣樹定理求出該位為1的所有邊的生成樹的個數,乘上該位的值,從而算出每一位的貢獻。

把每一位的貢獻加起來除以生成樹的總個數,便是期望。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=110;
 5 const int M=1e4+10;
 6 const int mod=998244353;
 7 struct edge{
 8     int from,to;
 9     ll d;
10 }e[M];
11 ll a[N][N];
12 ll ans;
13 int n,m;
14 ll quick_pow(ll x,ll y){
15     ll res=1;
16     while(y){
17         if(y&1) res=res*x%mod;
18         x=x*x%mod;
19         y>>=1;
20     }
21     return res;
22 }
23 void work(){
24     for(int i=2;i<=n;i++){
25         if(!a[i][i])
26         for(int j=i+1;j<=n;j++){
27             if(a[j][i]){
28                 ans=-ans;
29                 swap(a[i],a[j]);
30                 break;
31             }
32         }
33         ll inv=quick_pow(a[i][i],mod-2);
34         for(int j=i+1;j<=n;j++){
35             ll tmp=a[j][i]*inv%mod;
36             for(int k=i;k<=n;k++){
37                 a[j][k]=(a[j][k]-a[i][k]*tmp%mod+mod)%mod;
38             }
39         }
40     }
41 }
42 void solve(ll lim){
43     ans=1;
44     for(int i=1;i<=n;i++)
45         for(int j=1;j<=n;j++)
46             a[i][j]=0;
47     for(int i=1;i<=m;i++){
48         int u=e[i].from,v=e[i].to;
49         ll w=e[i].d;
50         if(!(w&lim)) continue;
51         a[u][u]++;
52         a[v][v]++;
53         a[u][v]--;
54         a[v][u]--;
55     }
56     work();
57     for(int i=2;i<=n;i++)
58         ans=(ans*a[i][i])%mod;
59     ans=(ans%mod+mod)%mod;
60 }
61 int main()
62 {
63     int T;
64     scanf("%d",&T);
65     while(T--){
66         scanf("%d%d",&n,&m);
67         for(int i=1;i<=m;i++){
68             scanf("%d%d%lld",&e[i].from,&e[i].to,&e[i].d);
69         }
70         ll x=0;
71         for(int i=0;i<30;i++){
72             ll lim=(1<<i);
73             solve(lim);
74             x=(x+lim*ans%mod)%mod;
75         }
76         solve((1<<30)-1);
77         ll sum=ans;
78         ll inv=quick_pow(sum,mod-2);
79         printf("%lld\n",x*inv%mod);
80     }
81     return 0;
82 }