zoukankan      html  css  js  c++  java
  • CSPS模拟69-72

    模拟69:

    T1,稍数学,主要还是dp(转移莫名像背包???),当C开到n2时复杂度为n4,考场上想了半天优化结果发现n是100,n4可过

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define N 100050
     7 #define mod 1000000007
     8 using namespace std;
     9 int n,c;
    10 long long m;
    11 int inc[N],inv[N];
    12 int dp[105][10005],f[2][105];
    13 inline int qpow(int d,long long z)
    14 {
    15     int ret=1;
    16     for(;z;z>>=1,d=1ll*d*d%mod)
    17         if(z&1)ret=1ll*ret*d%mod;
    18     return ret;
    19 }
    20 inline int C(int n,int m){return 1ll*inc[n]*inv[m]%mod*inv[n-m]%mod;}
    21 void init(int n)
    22 {
    23     inc[0]=inv[0]=1;
    24     for(int i=1;i<=n;++i)inc[i]=1ll*inc[i-1]*i%mod;
    25     inv[n]=qpow(inc[n],mod-2);
    26     for(int i=n-1;i;--i)inv[i]=1ll*inv[i+1]*(i+1)%mod;
    27 }
    28 int main()
    29 {
    30     cin>>n>>m>>c;init(n*n);
    31     if(m==n){printf("%d
    ",C(n*n,c));return 0;}
    32     long long t1=m/n,t2=m%n;
    33     for(register int i=0;i<=n;++i)
    34     {
    35         f[0][i]=qpow(C(n,i),t1);
    36         f[1][i]=1ll*f[0][i]*C(n,i)%mod;
    37     }
    38     dp[0][0]=1;
    39     for(int i=1,z;i<=n;++i)
    40     {
    41         if(i<=t2)z=1;
    42         else z=0;
    43         for(int j=0;j<=n;++j)
    44         {
    45             for(int k=0;k+j<=c;++k)
    46             {
    47                 dp[i][k+j]+=1ll*dp[i-1][k]*f[z][j]%mod;
    48                 if(dp[i][k+j]>=mod)dp[i][k+j]-=mod;
    49             }
    50         }
    51     }
    52     printf("%d
    ",dp[n][c]);
    53     return 0;
    54 }
    View Code

    T2:稍语文,考场上读错题,结果炸成0分。。。正解是单调栈,由于过于简单,直接粘代码

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define N 10000007
     6 using namespace std;
     7 const int inf=1000000007;
     8 int a[N],dp[N],n,ans=1;
     9 int pos[N],dq[N],mi[N],ba;
    10 inline int read()
    11 {
    12     int s=0,b=0;char c=getchar();
    13     while(c>'9'||c<'0')c=getchar();
    14     while(c>='0'&&c<='9')s=s*10+c-'0',c=getchar();
    15     return s;
    16 }
    17 int main()
    18 {
    19     n=read();if(!n){puts("0");return 0;}
    20     for(register int i=1;i<=n;++i)a[i]=read(),mi[i]=a[i],pos[i]=i;
    21     mi[0]=a[0]=inf;ba=1;pos[0]=0;
    22     for(register int i=1;i<=n;++i)
    23     {
    24         while(a[i]>=a[dq[ba]])
    25         {
    26             ans=max(ans,i-pos[dq[ba]]+1);
    27             if(mi[dq[ba]]<mi[dq[ba-1]]){
    28                 mi[dq[ba-1]]=mi[dq[ba]];
    29                 pos[dq[ba-1]]=pos[dq[ba]];
    30             }
    31             --ba;
    32         }
    33         if(a[i]>=mi[dq[ba]])
    34         {
    35             ans=max(ans,i-pos[dq[ba]]+1);
    36         }
    37         dq[++ba]=i;
    38     }
    39     printf("%d
    ",ans);
    40     return 0;
    41 }
    View Code

    T3:稍原题,回滚莫队。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define N 100050
     7 using namespace std;
     8 inline int read()
     9 {
    10     int s=0,b=0;char c=getchar();
    11     while(c>'9'||c<'0')c=getchar();
    12     while(c>='0'&&c<='9')s=s*10+c-'0',c=getchar();
    13     return s;
    14 }
    15 int a[N],n,m,sq,fl[N],fr[N],pd[N],al;
    16 inline int Max(int a,int b){if(a>b)return a;return b;}
    17 inline int Min(int a,int b){if(a>b)return b;return a;}
    18 int ans[N];
    19 struct node{
    20     int l,r,id;
    21     friend bool operator <(const node &a,const node &b)
    22     {
    23         if(a.l/sq==b.l/sq)return a.r<b.r;
    24         return a.l<b.l;
    25     }
    26 }q[N];
    27 void add(int x)
    28 {
    29     pd[x]=1;
    30     if(pd[x-1])
    31     {
    32         fl[x]=fl[x-1];
    33         fr[fl[x]]=x;
    34         al=Max(al,x-fl[x]+1);
    35     }
    36     if(pd[x+1])
    37     {
    38         fr[x]=fr[x+1];
    39         fl[fr[x]]=fl[x];
    40         fr[fl[x]]=fr[x];
    41         al=Max(al,fr[x]-fl[x]+1);
    42     }
    43     al=Max(al,fr[x]-fl[x]+1);
    44 }
    45 void del(int x)
    46 {
    47     if(pd[x+1])fl[fr[x]]=x+1;
    48     if(pd[x-1])fr[fl[x]]=x-1;
    49     fl[x]=fr[x]=x;pd[x]=0;
    50 }
    51 int main()
    52 {
    53 //    freopen("da.in","r",stdin);freopen("my.out","w",stdout);
    54     n=read();m=read();
    55     sq=sqrt(n);
    56     for(int i=1;i<=n;++i)a[i]=read(),fl[i]=fr[i]=i;
    57     for(int j=1;j<=m;++j)q[j].l=read(),q[j].r=read(),q[j].id=j;
    58     sort(q+1,q+m+1);
    59     int l=sq,r=sq,ks=sq;--r;
    60     for(int i=1,lastal=0;i<=m;++i)
    61     {
    62 //        printf("i:%d tol:%d tor:%d
    ",i,q[i].l,q[i].r);
    63         if(q[i].l/sq>q[i-1].l/sq)
    64         {
    65             for(int j=l;j<=r;++j)fl[a[j]]=fr[a[j]]=a[j],pd[a[j]]=0;
    66             al=lastal=0;ks=l=r=(q[i].l/sq+1)*sq;--r;
    67         }
    68         if(q[i].l/sq==q[i].r/sq)
    69         {
    70             al=0;
    71             for(int j=q[i].l;j<=q[i].r;++j)add(a[j]);
    72             ans[q[i].id]=al;
    73             for(int j=q[i].l;j<=q[i].r;++j)
    74                 fl[a[j]]=fr[a[j]]=a[j],pd[a[j]]=0;
    75             al=0;
    76             continue;
    77         }
    78         //puts("yes");
    79         while(r<q[i].r)add(a[++r]);
    80 //        printf("al1:%d
    ",al);
    81         lastal=al;
    82         while(l>q[i].l)add(a[--l]);
    83         ans[q[i].id]=al;
    84 //        printf("al2:%d
    ",al);
    85         while(l<ks)del(a[l++]);
    86         al=lastal;
    87     }
    88     for(int i=1;i<=m;++i)
    89         printf("%d
    ",ans[i]);
    90     return 0;
    91 }
    View Code

    模拟70:

    T1:(由于此题已被各种方式*爆证明,直接粘)

     1 //数论,gcd,根号
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<cmath>
     7 using namespace std;
     8 long long n,ans;
     9 long long p[30],c[30];
    10 int tot;
    11 inline void fen(long long n)
    12 {
    13     tot=0;
    14     for(register int i=2;i<=sqrt(n);++i)
    15     {
    16         if(n%i)continue;
    17         p[++tot]=i;c[tot]=0;
    18         while(n%i==0)++c[tot],n/=i;
    19     }
    20     if(n!=1)p[++tot]=n,c[tot]=1;
    21     
    22 }
    23 inline void getans(long long al)
    24 {
    25     if(n/al>al)return;
    26     if(n-al<al)return;
    27     ans+=n/al-1;
    28 }
    29 void sear(int t,long long al)
    30 {
    31     if(t>tot){getans(al);return;}
    32     const int m=(c[t]+1)/2;
    33     for(int i=1;i<=m;++i)al*=p[t];
    34         sear(t+1,al);
    35 }
    36 int main()
    37 {
    38 //    freopen("da.in","r",stdin);
    39     while(1)
    40     {
    41         scanf("%lld",&n);
    42         if(!n)return 0;
    43         ans=0;fen(n);
    44         sear(1,1ll);
    45         ans*=8;
    46         cout<<ans<<endl;
    47     }
    48 }
    View Code

    T2:(由于数据过水,暴力可过),正解复杂度带根号,用链表维护不同数的数量。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<bitset>
     7 #define N 40050
     8 using namespace std;
     9 int n,m;
    10 int dp[N],ans,a[N];
    11 bitset<N>pd;
    12 inline int Min(const int a,const int b){if(a<b)return a;return b;}
    13 int pre[N],las[N],num[N],ne[N],tot,tp,pos[N];
    14 struct node{int pre,ne,val,rk;}q[N];
    15 void work2()
    16 {
    17     int al=0,ans=0;
    18     for(int i=1;i<=n;++i)
    19     {
    20 //        printf("i:%d
    ",i);
    21         dp[i]=dp[i-1]+1;
    22         if(!pos[a[i]]){++tot;
    23             q[tot].pre=tp;q[tot].rk=i;
    24             q[tp].ne=tot;tp=tot;
    25             pos[a[i]]=tot;
    26         }
    27         else
    28         {
    29             if(pos[a[i]]!=tp)
    30             {
    31                 int t=pos[a[i]],tl=q[t].pre,tr=q[t].ne;
    32                 q[tl].ne=tr;q[tr].pre=tl;
    33                 q[t].rk=i;q[tp].ne=t;q[t].pre=tp;tp=t;
    34             }
    35             else
    36             {
    37                 q[tp].rk=i;
    38             }
    39             for(int j=q[tp].pre,t=1;j;j=q[j].pre,++t)
    40             {
    41                 if(t*t>i)break;
    42                 dp[i]=Min(dp[i],dp[q[j].rk]+t*t);
    43             }
    44         }
    45     }
    46     printf("%d
    ",dp[n]);
    47 }
    48 int main()
    49 {
    50     scanf("%d%d",&n,&m);ans=Min(n,m*m);
    51     for(int i=1;i<=n;++i)scanf("%d",&a[i]);
    52     pd.reset();work2();
    53 }
    View Code

    T3:(由于出题人咕咕咕,咕掉了)已更

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 #define N 2000
      7 using namespace std;
      8 const int dx[8]={-3,0,3,0,-2,-2,2,2};
      9 const int dy[8]={0,-3,0,3,-2,2,-2,2};
     10 int n,ok,kkk;
     11 int tp,bt,le,ri,tox,toy,tag;
     12 int ans[N][N];
     13 int zt[7][7][7][7][7][7];
     14 inline int poss(int x){return (x-1)/5+1;}
     15 inline void getne(int x,int y)
     16 {
     17     if(poss(x)==1&&poss(y)!=1){tox=x;toy=y-3;tag=2;return;}
     18     if(poss(y)*5==n){tox=x-3;toy=y;tag=1;return;}
     19     if(poss(x)==2)
     20     {
     21         if(n==10){
     22             if(poss(y)&1){tox=x;toy=y+3;tag=4;return;}
     23             else{tox=x-3;toy=y;tag=1;return;}
     24         }
     25         
     26         if(poss(y)&1){tox=x+3;toy=y;tag=3;return;}
     27         else{
     28             if(poss(y)==n/5){tox=x-3;toy=1;tag=1;return;}
     29             else{tox=x;toy=y+3;tag=4;return;}
     30         }
     31     }
     32     if(poss(x)==n/5){
     33         if(poss(y)&1){tox=x;toy=y+3;tag=4;return;}
     34         else{tox=x-3;toy=y;tag=1;return;}
     35     }
     36     else{
     37         if(poss(y)&1){tox=x+3;toy=y;tag=3;return;}
     38         else{tox=x-3;toy=y;tag=1;return;}
     39     }
     40 }
     41 
     42 inline void getne2(int x,int y)
     43 {
     44     if(poss(x)==1&&poss(y)!=1){tox=x;toy=y-3;tag=2;return;}
     45     if(poss(y)==n/5||poss(y)==n/5-1)
     46     {
     47         if(poss(y)==n/5)
     48         {
     49             if(poss(x)&1){tox=x-3;toy=y;tag=1;return;}
     50             else{tox=x;toy=y-3;tag=2;return;}
     51         }
     52         else
     53         {
     54             if(poss(x)==2){tox=x-2;toy=y+2;tag=5;return;}
     55             if(poss(x)&1){tox=x;toy=y+3;tag=4;return;}
     56             else{tox=x-3;toy=y;tag=1;return;}
     57         }
     58     }
     59     if(poss(y)*5==n){tox=x-3;toy=y;tag=1;return;}
     60     if(poss(x)==2)
     61     {
     62         if(n==10){
     63             if(poss(y)&1){tox=x;toy=y+3;tag=4;return;}
     64             else{tox=x-3;toy=y;tag=1;return;}
     65         }
     66         
     67         if(poss(y)&1){tox=x+3;toy=y;tag=3;return;}
     68         else{
     69             if(poss(y)==n/5){tox=x-3;toy=1;tag=1;return;}
     70             else{tox=x;toy=y+3;tag=4;return;}
     71         }
     72     }
     73     if(poss(x)==n/5){
     74         if(poss(y)&1){tox=x;toy=y+3;tag=4;return;}
     75         else{tox=x-3;toy=y;tag=1;return;}
     76     }
     77     else{
     78         if(poss(y)&1){tox=x+3;toy=y;tag=3;return;}
     79         else{tox=x-3;toy=y;tag=1;return;}
     80     }
     81 }
     82 void sear(int x,int y,int al)
     83 {
     84     
     85     if(al==n*n-1)return;
     86     if(n&1)getne2(x,y);
     87     else getne(x,y);
     88 
     89     x=tox;y=toy;
     90     
     91     if(n&1)getne2(tox,toy);
     92     else getne(tox,toy);
     93     
     94     int bx,by;bx=poss(x)*5-4;by=poss(y)*5-4;
     95     switch(tag)
     96     {
     97         case 1:{tox=bx;toy=by+2;break;}
     98         case 2:{tox=bx+2;toy=by;break;}
     99         case 3:{tox=bx+4;toy=by+2;break;}
    100         case 4:{tox=bx+2;toy=by+4;break;}
    101         case 5:{tox=bx;toy=by+4;break;}
    102     }
    103     if(tox==x&&toy==y)--toy;
    104     for(int i=bx;i<=bx+4;++i)
    105         for(int j=by;j<=by+4;++j)
    106             ans[i][j]=zt[x-bx+1][y-by+1][tox-bx+1][toy-by+1][i-bx+1][j-by+1]+al;
    107     al+=25;
    108     sear(tox,toy,al);
    109 }
    110 void dfs(int f1,int f2,int t1,int t2,int x,int y,int p)
    111 {
    112     zt[f1][f2][t1][t2][x][y]=p;
    113     if(p==25){
    114         if(x==t1&&y==t2){ok=1;return;}
    115         zt[f1][f2][t1][t2][x][y]=0;
    116         return;
    117     
    118     }
    119     if(x==t1&&y==t2){
    120         zt[f1][f2][t1][t2][x][y]=0;
    121         return;
    122     }
    123     for(register int j=0;j<=7;++j)
    124     {
    125         if(x+dx[j]<=0||x+dx[j]>5||y+dy[j]<=0||y+dy[j]>5||zt[f1][f2][t1][t2][x+dx[j]][y+dy[j]])continue;
    126         dfs(f1,f2,t1,t2,x+dx[j],y+dy[j],p+1);if(ok)return;
    127     }
    128     zt[f1][f2][t1][t2][x][y]=0;
    129 }
    130 void pr(int x,int y,int xx,int yy)
    131 {
    132     for(int i=1;i<=5;++i){
    133         for(int j=1;j<=5;++j)
    134             printf("%3d ",zt[x][y][xx][yy][i][j]);
    135         puts("");
    136     }
    137 }
    138 void prans()
    139 {
    140     for(int i=1;i<=n;++i){
    141         for(int j=1;j<=n;++j)
    142             printf("%3d ",ans[i][j]);
    143         puts("");
    144     }
    145 }
    146 int main()
    147 {
    148     cin>>n;kkk=5*5+1;
    149     for(int i=1;i<=5;++i)
    150         for(int j=1;j<=5;++j)
    151             for(int k=1;k<=5;++k)
    152                 for(int o=1;o<=5;++o)
    153                     {if(k==i&&o==j)continue;ok=0;dfs(i,j,k,o,i,j,1);}
    154     for(int i=1;i<=5;++i)
    155         for(int j=1;j<=5;++j)
    156             ans[i][j]=zt[1][1][3][3][i][j];
    157     ans[3][3]=n*n;
    158     if(n==5){prans();return 0;}
    159     sear(5,5,24);prans();
    160 }
    View Code

    模拟71

    T1:正解为meet in the mid,但用乱搞加剪枝可过

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<vector>
     7 using namespace std;
     8 const int mod=233337;
     9 const int N=(1<<20)+100;
    10 struct hash_map{
    11     int a[N],tot;
    12     int he[mod];
    13     int ne[N];
    14     int val[N];
    15     int to[N];
    16     inline void add(int x,int t)
    17     {
    18         int k=x%mod;
    19         to[++tot]=t;val[tot]=x;
    20         ne[tot]=he[k];he[k]=tot;
    21     }
    22     int operator [](int x)
    23     {
    24         int k=x%mod;
    25         for(int i=he[k];i;i=ne[i])
    26             if(val[i]==x)return to[i];
    27         return 0;
    28     }
    29 }h;
    30 int n,tot,ans,b[N];
    31 vector<int>v[N];
    32 int bin[N];
    33 int a[30];
    34 inline int count(int x)
    35 {
    36     int ret=0;
    37     for(int i=0;i<n;++i)
    38         if(x&bin[i])++ret;
    39     return ret;
    40 }
    41 int main()
    42 {
    43     scanf("%d",&n);for(int i=0;i<=n;++i)bin[i]=1<<i;
    44     int p=0;
    45     for(int i=0;i<n;++i)scanf("%d",&a[i]);
    46     int gc=a[0];
    47     for(int i=1;i<n;++i)gc=__gcd(gc,a[i]);
    48     for(int j=0;j<n;++j)a[j]/=gc,p+=a[j];
    49     p=(p+1)>>1;
    50     const int ma=1<<n;
    51     for(register int i=1,al,t;i<ma;++i)
    52     {
    53         al=0;
    54         for(register int j=0;j<n;++j)
    55             if(i&bin[j])al+=a[j];
    56         b[i]=al;
    57         if(al&1)
    58         {
    59             if(al<=p)
    60             {
    61                 if(!h[al])h.add(al,++tot);
    62                 v[h[al]].push_back(i);
    63             }
    64             continue;
    65         }
    66         else
    67         {
    68             t=al>>1;
    69             if(h[t])
    70             {
    71                 t=h[t];
    72                 if(bin[count(i)]<v[t].size())
    73                 {
    74                     t=al>>1;
    75                     for(register int j=i;j;j=(j-1)&i)
    76                         if(b[j]==t){++ans;break;}
    77                 }
    78                 else
    79                 {
    80                     for(register int j=0;j<v[t].size();++j)
    81                         if((v[t][j]&i)==v[t][j]){++ans;break;}
    82                 }
    83             }
    84             if(al<=p)
    85             {
    86                 if(h[al]==0)h.add(al,++tot);
    87                 v[h[al]].push_back(i);
    88             }
    89         }
    90     }
    91     cout<<ans<<endl;
    92 }
    View Code

    打爆毛一琛轻轻松松

    T2:我以前做过一个很SAO的题,叫做SAO,然后这题转化一下题意就和SAO很像,反正巨恶心,考场上凭借做过SAO拿到70。

    关于SAO的blogs:https://www.cnblogs.com/loadingkkk/p/11220717.html

    转化题意考虑一开始有一个1到n的序列,要把它通过一个1到n-1的序列转换成目标序列,考虑构造这个n-1的序列发现从目标序列一直跳(int i=n;i!=1;i=p[i])可以把顺序找出来

    dp数组是定义在1~n-1的序列上的,然后dp[i][j]定义为考虑到序列上从i到n-1,i在构造的序列中的排名为j的方案数,dp时维护前缀和即可。

     1 #include<iostream>
     2 #include<cstdio>
     3 #define N 5050
     4 using namespace std;
     5 const int mod=1000000007;
     6 int n,a[N],ans,dp[N][N],pd[N];
     7 int main()
     8 {
     9     scanf("%d",&n);for(int i=1;i<=n;++i)scanf("%d",&a[i]),++a[i];
    10     if(a[n]==n){puts("0");return 0;}
    11     int pre=a[n];
    12     for(int j=n;j>=1;--j)if(pre==j){pd[j]=1;pre=a[pre];}
    13     dp[n-1][1]=1;
    14     for(int i=n-2,al;i;--i){al=n-i-1;
    15         if(pd[i+1])for(int o=1,tt=0;o<=al+1;++o){dp[i][o]=tt;tt+=dp[i+1][o];if(tt>=mod)tt-=mod;}
    16         else for(int o=al,tt=0;o;--o){tt+=dp[i+1][o];if(tt>=mod)tt-=mod;dp[i][o]=tt;}
    17     }
    18     for(int i=1;i<=n-1;++i){ans+=dp[1][i];if(ans>=mod)ans-=mod;}
    19     cout<<ans<<endl;
    20 }
    View Code

    T3:这是一个复杂度和证明都很玄学的算法(......剪枝完暴力搜

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<map>
     6 #include<vector>
     7 #define N 10050
     8 using namespace std;
     9 int n,a[N],p,k,ans;
    10 inline bool judge(const int x,const int ans)
    11 {
    12     const int mod=p;
    13     register int ret=1,al=0;
    14     for(register int i=1,to;i<=n;++i)
    15     {
    16         to=a[i]+x;if(to>=mod)to-=mod;
    17         if(to>ans)return false;
    18         if(al+to>ans){
    19             al=0;++ret;
    20             if(ret>k)return false;
    21         }
    22         al+=to;
    23     }
    24     return true;
    25 }
    26 void work(const int x)
    27 {
    28     int l=0,r=ans,mid;
    29     while(l+1<r)
    30     {
    31         mid=l+r>>1;
    32         if(judge(x,mid))r=mid;
    33         else l=mid;
    34     }
    35     ans=r;
    36 }
    37 int main()
    38 {
    39     scanf("%d%d%d",&n,&p,&k);
    40     for(int i=1;i<=n;++i)scanf("%d",&a[i]),ans+=a[i];
    41     for(int i=0,ma;i<p;i+=p-ma)
    42     {
    43         if(judge(i,ans))work(i);
    44         ma=0;
    45         for(int j=1,to;j<=n;++j)
    46         {
    47             to=a[j]+i;if(to>=p)to-=p;
    48             if(to>ma)ma=to;
    49         }
    50     }
    51     cout<<ans<<endl;
    52 }
    View Code

    模拟72:

    T1:水,dp or 卡特兰

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int mod=1000000007;
     7 int n,m,dp[2050][2050][2],mu,al,ans;
     8 char s[100050];
     9 int main()
    10 {
    11     scanf("%d%d%s",&n,&m,s+1);
    12     for(int i=1;i<=m;++i){
    13         if(s[i]=='(')++al;
    14         else
    15         {
    16             if(al)--al;
    17             else ++mu;
    18         }
    19     }
    20     if(mu>n-m||al>n-m){puts("0");return 0;}
    21     if(n==m)
    22     {
    23         if(!mu&&!al){puts("1");return 0;}
    24         else {puts("0");return 0;}
    25     }
    26     dp[0][0][0]=1;dp[1][1][0]=1;
    27     if(!mu)
    28     {
    29         dp[1][al+1][1]=1;
    30         if(al)dp[1][al-1][1]=1;
    31     }
    32     for(register int i=2;i<=n-m;++i)
    33     {
    34         dp[i][0][0]=dp[i-1][1][0];dp[i][0][1]=dp[i-1][1][1];
    35         for(int j=1;j<=i;++j)
    36         {
    37             dp[i][j][0]=dp[i-1][j-1][0]+dp[i-1][j+1][0];
    38             if(dp[i][j][0]>=mod)dp[i][j][0]-=mod;
    39             dp[i][j][1]=dp[i-1][j-1][1]+dp[i-1][j+1][1];
    40             if(dp[i][j][1]>=mod)dp[i][j][1]-=mod;
    41         }
    42         for(int j=i+1;j<=n-m;++j)
    43         {
    44             dp[i][j][1]=dp[i-1][j-1][1]+dp[i-1][j+1][1];
    45             if(dp[i][j][1]>=mod)dp[i][j][1]-=mod;
    46         }
    47         for(int j=mu;j-mu+al<=n-m;++j)
    48         {
    49             dp[i][j-mu+al+1][1]+=dp[i-1][j][0];
    50             if(dp[i][j-mu+al+1][1]>=mod)dp[i][j-mu+al+1][1]-=mod;
    51             if(j-mu+al-1>=0)
    52             {
    53                 dp[i][j-mu+al-1][1]+=dp[i-1][j][0];
    54                 if(dp[i][j-mu+al-1][1]>=mod)dp[i][j-mu+al-1][1]-=mod;
    55             }
    56         }
    57     }
    58     ans=dp[n-m][0][1];
    59     if(!al)
    60     {
    61         ans+=dp[n-m][mu][0];
    62         if(ans>=mod)ans-=mod;
    63     }
    64     cout<<ans<<endl;
    65     return 0;
    66 }
    View Code

    T2:主要在于dp状态设定,转移很简单

    设dp[i][j][2][k]表示进行了i次操作,当前数二进制表示下后8位为j,第九位为0/1,第九位往前连续k位相同的概率

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<vector>
     6 #include<stack>
     7 #include<queue>
     8 #define N 5050
     9 using namespace std;
    10 const double di=0.01;
    11 int n,m,sta,t,cnt;
    12 long long x;
    13 double dp[205][1<<8][2][300];
    14 double ans,p,q;
    15 int bin[32];
    16 int main()
    17 {
    18     for(int i=0;i<=30;++i)bin[i]=1<<i;
    19     scanf("%lld%d%lf",&x,&n,&p);p*=0.01;q=1.0-p;
    20     for(int i=0;i<8;++i)sta|=x&bin[i];
    21     t=(x>>8)&1;cnt=1;
    22     for(int i=9;i<=30;++i)
    23     {
    24         if(((x>>i)&1)==t)++cnt;
    25         else break;
    26     }
    27     const int ma=1<<8;
    28     dp[0][sta][t][cnt]=1;
    29     for(int i=0;i<n;++i){
    30         for(int j=0;j<ma;++j){
    31             for(int k=1;k<=n+32;++k){
    32                     if(j&bin[7])dp[i+1][(j<<1)^bin[8]][1][1]+=dp[i][j][0][k]*p;
    33                     else dp[i+1][(j<<1)][0][k+1]+=dp[i][j][0][k]*p;
    34                     if(j==255)dp[i+1][0][1][1]+=dp[i][j][0][k]*q;
    35                     else dp[i+1][j+1][0][k]+=dp[i][j][0][k]*q;
    36                     if(j&bin[7])dp[i+1][(j<<1)^bin[8]][1][k+1]+=dp[i][j][1][k]*p;
    37                     else dp[i+1][(j<<1)][0][1]+=dp[i][j][1][k]*p;
    38                     if(j==255)dp[i+1][0][0][k]+=dp[i][j][1][k]*q;
    39                     else dp[i+1][j+1][1][k]+=dp[i][j][1][k]*q;
    40             }
    41         }
    42     }
    43     for(int j=1,d,x;j<ma;++j)
    44     {
    45         x=j;d=0;
    46         while(!(x&1))x>>=1,++d;
    47         for(int k=1;k<=n+32;++k)ans+=(dp[n][j][0][k]+dp[n][j][1][k])*d;
    48     }
    49     for(int k=1;k<=n+32;++k)
    50     {
    51         ans+=dp[n][0][1][k]*8;
    52         ans+=dp[n][0][0][k]*(8+k);
    53     }
    54     printf("%.10lf
    ",ans);
    55 }
    View Code

    T3:

    先考虑连通图的情况。
    首先如果原图不是二分图,显然无解。因为对于一个长度大于3的奇环,如果合并环上任意两个不相邻的点,一定会生成一个更小的奇环,最终会剩下一个三元环,无法继续合并。
    对于任意联通的二分图,我们可以选定一个点s ,然后将所有与s距离相同的点合并。由于原图是二分图,所有与距离相同的点必然在同一侧,也就一定不相邻,这样就可以构造出一条链。因此只需要找出两个点,使得它们间的最短路径最长。显然这样构造是最优的。
    考虑有多个连通分量的情况,我们对于每一个连通分量都构造了一条链,而对于任意两条链,我们显然可以通过一次合并操作将它们并成一条,长度为它们的长度之和。因此,答案就是所有连通块的直径之和。
    使用 BFS 求出最短路,时间复杂度为n2

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<vector>
     6 #include<stack>
     7 #include<queue>
     8 #define N 5050
     9 using namespace std;
    10 int n,m,ok=1;
    11 int he[N],ne[500050],to[500050],tot;
    12 void addedge(int x,int y){to[++tot]=y;ne[tot]=he[x];he[x]=tot;}
    13 int f[N],ans[N];
    14 int dfn[N],low[N],ys[N],cut[N],cnt,rt,kx,bl[N];
    15 vector<int>scc[N];
    16 stack<int>st;
    17 //
    18 int dis[1200][1200];
    19 queue<int>q;
    20 void dijiesitela(const int g)
    21 {
    22     dis[g][g]=1;int x,y;
    23     q.push(g);
    24     while(!q.empty())
    25     {
    26         x=q.front();q.pop();
    27         for(int i=he[x];i;i=ne[i])
    28         {
    29             y=to[i];
    30             if(dis[g][y])continue;
    31             dis[g][y]=dis[g][x]+1;
    32             q.push(y);
    33         }
    34     }
    35 }
    36 void tarjan(int g,int fa)
    37 {
    38     f[g]=rt;
    39     for(int i=he[g],y;i;i=ne[i])
    40     {
    41         y=to[i];if(y==fa)continue;
    42         if(ys[y]){if(ys[y]==ys[g]){ok=0;return;}}
    43         else{ys[y]=ys[g]^1;tarjan(y,g);}
    44     }
    45 }
    46 int main()
    47 {
    48     scanf("%d%d",&n,&m);
    49     for(register int i=1,x,y;i<=m;++i)
    50     {
    51         scanf("%d%d",&x,&y);
    52         addedge(x,y);addedge(y,x);
    53     }
    54     for(int i=1;i<=n;++i)
    55         dijiesitela(i);
    56     for(int i=1;i<=n;++i)
    57         if(!f[i]){
    58             ys[i]=2;rt=i;tarjan(i,0);
    59             if(!ok){puts("-1");return 0;}
    60         }
    61     for(int i=1;i<=n;++i)
    62         for(int j=1;j<=n;++j)
    63             if(f[j]==f[i])ans[f[j]]=max(ans[f[j]],dis[i][j]-1);
    64     int alans=0;
    65     for(int i=1;i<=n;++i)alans+=ans[i];
    66     cout<<alans<<endl;
    67 }
    View Code
  • 相关阅读:
    js 面试的坑:变量提升
    meta 标签大全
    一个极为简单的requirejs实现
    AMD 的 CommonJS wrapping
    浅解析js中的对象
    javascript运动系列第二篇——变速运动
    开发汉澳即时通信网,2006年上线,QQ死期到了
    SpringMVC中的异步提交表单
    HDU 3698 DP+线段树
    黑马程序猿_反射、内省、泛型
  • 原文地址:https://www.cnblogs.com/loadingkkk/p/11669482.html
Copyright © 2011-2022 走看看