• NOIP模拟测试2-5


    该补一下以前挖的坑了

    先总结一下

    第二次

    T1 搜索+剪枝

      1 #include<cstdio>
      2 #include<iostream>
      3 #define ll long long
      4 using namespace std;
      5 const int maxn=8005;
      6 int a[maxn],n,js[maxn];
      7 bool jk[maxn];
      8 ll ans;
      9 bool judge(int l,int r)
     10 {
     11     int i=l;
     12     while(i<r)
     13     {
     14         if(a[i]+1!=a[i+1])return 0;
     15         else i++;
     16     }
     17     return 1;
     18 }
     19 void out()
     20 {
     21     for(int i=1;i<=(1<<n);i++)
     22     {
     23         cout<<a[i]<<" ";
     24     }
     25     cout<<endl;
     26 }
     27 void search(int num,int last)
     28 {
     29    //out();//cout<<"->"<<endl;
     30     if(judge(1,1<<n)){ans+=js[num];return ;}
     31     if(last==n+1)return ;
     32     int must1=0,must2=0;
     33     for(int j=1;j<=(1<<n);j+=(1<<last))
     34         {
     35             if(!judge(j,j+(1<<last)-1)&&!must1)must1=j;
     36             else if(!judge(j,j+(1<<last)-1)&&must1&&!must2)must2=j;
     37             else if(!judge(j,j+(1<<last)-1))return ;
     38         }
     39     if(!must1&&!must2)search(num,last+1);
     40     else if(!must2)
     41     {
     42         int j=must1,k=must1+(1<<(last-1));
     43         int kx=0;
     44         while(kx<(1<<(last-1)))
     45         {
     46              swap(a[j+kx],a[k+kx]);
     47              kx++;
     48         }
     49         search(num+1,last+1);
     50         kx=0;
     51         while(kx<(1<<(last-1)))
     52         {
     53              swap(a[j+kx],a[k+kx]);
     54              kx++;
     55         }
     56         return ;
     57     }
     58     else
     59     {
     60         int jj[2]={},kk[2]={};
     61        // cout<<must1<<" "<<must2<<endl;
     62        jj[0]=must1,jj[1]=must1+(1<<(last-1));
     63        kk[0]=must2,kk[1]=must2+(1<<(last-1));
     64        //cout<<jj[1]<<" "<<kk[1]<<endl;
     65        for(int i=0;i<=1;i++)
     66            for(int j=0;j<=1;j++)
     67            {
     68                 //out();
     69                 //cout<<jj[i]<<" "<<kk[j]<<endl;
     70                 int kx=0;
     71                 while(kx<(1<<(last-1)))
     72                 {
     73                       swap(a[jj[i]+kx],a[kk[j]+kx]);
     74                       kx++;
     75                 }
     76                 search(num+1,last+1);
     77                 kx=0;
     78                 while(kx<(1<<(last-1)))
     79                 {
     80                       swap(a[jj[i]+kx],a[kk[j]+kx]);
     81                       kx++;
     82                 }
     83                 
     84            }
     85     }
     86     return ;
     87 }
     88 int main()
     89 {
     90     scanf("%d",&n);
     91     js[1]=1;
     92     for(int i=2;i<=n;i++)
     93         js[i]=js[i-1]*i;
     94     for(int i=1;i<=(1<<n);i++)
     95     {
     96         scanf("%d",&a[i]);
     97     }
     98         search(0,1);
     99         cout<<ans<<endl;
    100         return 0;
    101 }
    View Code

    T2 划艇 高难标记

    31分算法:线段树优化DP 

    AC算法:

    区间离散化。

    跨区间显然,同区间组合计数。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #define mod DeepinC
     5 #define maxn 505
     6 using namespace std;
     7 int l[maxn*2],len[maxn*2],sum[maxn*2][maxn*2],num[maxn*2][maxn*2],a[maxn],b[maxn],f[maxn][maxn*2],inv[maxn*10+5];
     8 const int mod=1e9+7;
     9 int qpower(int a,int b)
    10 {
    11     int ans=1;
    12     while(b)
    13     {
    14         if(b&1)ans=1ll*ans*a%mod;
    15         b>>=1;
    16         a=1ll*a*a%mod;
    17     }
    18     return ans;
    19 }
    20 void get_inv()
    21 {
    22     for(int i=1;i<=500;i++)
    23         inv[i]=qpower(i,mod-2);
    24     return ;
    25 }
    26 int main()
    27 {
    28     get_inv();
    29     int n,tot=0,ans=0;
    30     scanf("%d",&n);
    31     for(int i=1;i<=n;i++)
    32     {
    33         scanf("%d%d",&a[i],&b[i]);
    34         b[i]++;
    35         l[++tot]=a[i];
    36         l[++tot]=b[i];
    37     }
    38     sort(l+1,l+tot+1);
    39     tot=unique(l+1,l+tot+1)-l-1;
    40     for(int i=1;i<tot;i++)
    41     {
    42         len[i]=l[i+1]-l[i];
    43         //cout<<i<<" "<<len[i]<<endl;
    44     }
    45     for(int i=1;i<=n;i++)
    46     {
    47         a[i]=lower_bound(l+1,l+tot+1,a[i])-l;
    48         b[i]=lower_bound(l+1,l+tot+1,b[i])-l-1;
    49     }
    50     sum[0][0]=1;
    51     for(int i=1;i<=n;i++)
    52     {
    53         sum[i][0]=1;
    54     }
    55     for(int j=1;j<=tot;j++)sum[0][j]=1;
    56     for(int i=1;i<=n;i++)
    57     {
    58         for(int j=a[i];j<=b[i];j++)
    59         {
    60             f[i][j]=1ll*sum[i-1][j-1]*len[j]%mod;
    61            // cout<<f[i][j]<<endl;
    62             int o=1,C=(len[j]-1)%mod;
    63             for(int k=i-1;k;k--)
    64             {
    65                 if(a[k]>j||b[k]<j)continue;
    66                 o++;
    67                 C=1ll*C*(o+len[j]-2)%mod*inv[o]%mod;
    68                 //cout<<C<<endl;
    69                 f[i][j]=(f[i][j]+1ll*C*sum[k-1][j-1]%mod)%mod;
    70             }
    71             ///cout<<f[i][j]<<endl;
    72             ans+=f[i][j];
    73             ans%=mod;
    74         }
    75         for(int j=1;j<=tot;j++)
    76             sum[i][j]=((1ll*sum[i-1][j]+sum[i][j-1])%mod-sum[i-1][j-1]+f[i][j]+mod)%mod;
    77     }       
    78     cout<<ans<<endl;
    79     return 0;
    80 }
    View Code

    T3 放棋子:DP

      设g[i][j][k]表示用k个棋子填满i行j列的方案,设f[i][j][k]表示用前k种棋子填满i行j列的方案

      容斥计算g数组: 

         

       那么f数组 :

        

       最终答案:

    (图片来自https://www.cnblogs.com/yanshannan/p/9467292.html,特此鸣谢)

    AC代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #define maxn 35
     5 using namespace std;
     6 const int mod=1e9+9;
     7 int C[maxn*maxn][maxn*maxn],g[maxn][maxn],f[maxn][maxn][maxn*maxn],cn[maxn];
     8 int moded(int x)
     9 {
    10     if(x<0)return x+mod;
    11     return x>=mod?x-mod:x;
    12 }
    13 int main()
    14 {
    15    // freopen("out.txt","w",stdout);
    16     int n,m,c,tot=0;
    17     scanf("%d%d%d",&n,&m,&c);
    18     for(int i=1;i<=c;i++)
    19     {
    20         scanf("%d",&cn[i]);
    21         tot=max(tot,cn[i]);
    22     }
    23     for(int i=1;i<=900;i++)
    24     {
    25         C[i][0]=C[i][i]=1;
    26         for(int j=1;j<i;j++)
    27             C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
    28     }
    29     f[0][0][0]=1;
    30     int ans=0;
    31     for(int k=1;k<=c;k++)
    32     {
    33         memset(g,0,sizeof(g));
    34         for(int i=1;i<=n;i++)
    35             for(int j=1;j<=m;j++)
    36                 {
    37                     g[i][j]=C[i*j][cn[k]];
    38                     for(int ii=0;ii<=i;ii++)
    39                         for(int jj=0;jj<=j;jj++)
    40                         {
    41                             if(ii==i&&jj==j)continue;
    42                             g[i][j]=(g[i][j]-1ll*g[ii][jj]*C[i][ii]%mod*C[j][jj]%mod+mod)%mod;
    43                         }
    44                     //cout<<k<<" "<<i<<" "<<j<<" "<<" "<<g[i][j]<<endl;
    45                 }
    46         for(int i=1;i<=n;i++)
    47             for(int j=1;j<=m;j++)
    48             {
    49                     for(int ii=0;ii<i;ii++)
    50                         for(int jj=0;jj<j;jj++)
    51                         {
    52                             f[i][j][k]=(f[i][j][k]+1ll*f[ii][jj][k-1]*C[n-ii][i-ii]%mod*C[m-jj][j-jj]%mod*g[i-ii][j-jj]%mod)%mod;
    53                             //if(k==c&&i==n&&j==m)cout<<ii<<" "<<jj<<" "<<f[ii][jj][k-1]<<endl;
    54                         }
    55                      if(k==c)
    56                      {
    57                         ans=moded(ans+f[i][j][c]);
    58                         //if(i==n)cout<<i<<" "<<j<<" "<<f[i][j][c]<<endl;
    59                      }
    60            }
    61         
    62    }
    63     cout<<ans<<endl;
    64     return 0;
    65 }
    View Code

    第三次

    爆零。。。

    T1:序列

    乱搞,(鬼知道我打了一个什么倍增)

    AC代码:(不会告诉你我是QJ的) 

    感谢wd大佬的帮助%%DeepinC

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<cstring>
      5 #define maxn 200005
      6 #define maxq 1001
      7 #include<vector>
      8 #include<algorithm>
      9 #define LL long long
     10 #define ts puts("--------");
     11 using namespace std;
     12 LL n,a[maxn],ans,need1[maxn],A[maxn],maxx,b[maxn][21],num[maxn],fr[maxn][21],Num[105],nuM[105],toty;
     13 LL prime[maxq*10000+5],tot,frprime[maxq*10000+5];
     14 bool isnotprime[maxq*10000+5];
     15 LL gcd(LL a,LL b)
     16 {
     17     return b==0?a:gcd(b,a%b);
     18 }
     19 LL qpower(LL a,LL b)
     20 {
     21     LL ans=1;
     22     while(b)
     23     {
     24         if(b&1)ans=ans*a;
     25         a=a*a;
     26         b>>=1;
     27     }
     28     return ans;
     29 }
     30 void pre()
     31 {
     32     for(int i=2;i<=maxq*10000;i++)
     33     {
     34         if(!isnotprime[i])
     35         {
     36             prime[++toty]=i;
     37             frprime[i]=i;
     38         }
     39         for(int j=1;j<=toty;j++)
     40         {
     41             if(i*prime[j]>maxq*10000)break;
     42             isnotprime[i*prime[j]]=1;
     43             frprime[i*prime[j]]=prime[j];
     44             if(!i%prime[j])break;
     45         }
     46     }
     47 }
     48 LL GetUse(LL x)
     49 {
     50     LL mt=x;
     51     if(x%10==0){
     52         while(x%10==0)x/=10;
     53         return x==1?10ll:mt;
     54     }
     55     if(x%7==0){
     56         while(x%7==0)x/=7;
     57         return x==1?7ll:mt;
     58     }
     59     if(x%6==0){
     60         while(x%6==0)x/=6;
     61         return x==1?6ll:mt;
     62     }
     63     if(x%5==0){
     64         while(x%5==0)x/=5;
     65         return x==1?5ll:mt;
     66     }
     67     if(x%3==0){
     68         while(x%3==0)x/=3;
     69         return x==1?3:mt;
     70     }
     71     if(x%2==0){
     72         while(x%2==0)x/=2;
     73         return x==1?2:mt;
     74     }
     75     return mt;
     76 }
     77 bool query(LL st,LL len)
     78 {
     79     LL cnt=0;
     80     for(LL i=st;i<=st+len-1;i++)
     81     {
     82         num[++cnt]=a[i];
     83     }
     84     sort(num+1,num+cnt+1);
     85     for(LL i=2;i<=cnt;i++)if(num[i]==num[i-1]){return 0;}
     86     return 1;
     87 }
     88 LL Get(LL x,LL q)
     89 {
     90     if(q==1)return x;
     91     while(x%q==0)x/=q;
     92     return x;
     93 }
     94 bool judge(LL len)
     95 {
     96     LL Q=0,now,F;
     97     for(LL i=1;i<=n-len+1;i++)
     98     {
     99         now=0;Q=0;
    100         for(LL t=17;t>=1;t--)
    101         {
    102             if((1<<t)+now<=len){
    103                 if(b[i+now][t]==-1){break;}
    104             //    cout<<i<<' '<<len<<' '<<t<<' '<<now<<" from "<<n-len+1<<endl;
    105                 if(!Q){Q=b[i+now][t];F=fr[i+now][t];}
    106                 else if(b[i+now][t]==-1||Q!=b[i+now][t]||fr[i+now][t]!=F){break;}
    107                 now+=(1<<t);
    108                 if(now==len){
    109                     if(Q==1||query(i,len))return 1;
    110                     else break;
    111                 }
    112                 if(now==len-1){
    113                     if(Q==1&&a[i+len-1]==a[i+len-2])return 1;
    114                     if(a[i+len-1]>a[i+len-2]&&query(i,len)&&a[i+len-1]%a[i+len-2]==0)
    115                     {
    116                         LL t=a[i+len-1]/a[i+len-2];
    117                         if(GetUse(t)==Q)return 1;
    118                     }
    119                     else 
    120                     if(a[i+len-1]<a[i+len-2]&&query(i,len)&&a[i+len-2]%a[i+len-1]==0)
    121                     {
    122                         LL t=a[i+len-2]/a[i+len-1];
    123                         if(GetUse(t)==Q)return 1;
    124                     }
    125                     break;
    126                 }
    127             }
    128         }
    129     }
    130     return 0;
    131 }
    132 int main()
    133 {
    134     scanf("%lld",&n);
    135     for(LL i=1;i<=n;i++)scanf("%lld",&a[i]);
    136     for(LL i=2;i<=n;i++)
    137         if(a[i]%a[i-1]==0){
    138             b[i-1][1]=a[i]/a[i-1];
    139             b[i-1][1]=GetUse(b[i-1][1]);
    140             fr[i-1][1]=Get(a[i-1],b[i-1][1]);
    141         }
    142         else if(a[i-1]%a[i]==0){
    143             b[i-1][1]=a[i-1]/a[i];
    144             b[i-1][1]=GetUse(b[i-1][1]);
    145             fr[i-1][1]=Get(a[i],b[i-1][1]);
    146         }
    147         else b[i-1][1]=-1;
    148     b[n][1]=-1;
    149     for(LL i=2;i<=17;i++)
    150         for(LL j=1;j<=n;j++){
    151             if(b[j][i-1]==b[j+(1<<(i-1))][i-1]&&b[j][i-1]!=-1&&fr[j][i-1]==fr[j+(1<<(i-1))][i-1])
    152                 b[j][i]=b[j][i-1],fr[j][i]=fr[j][i-1];
    153             else b[j][i]=-1;
    154         }
    155     LL l=2,r=n;
    156     while(l<=r)
    157     {
    158         int mid=l+r>>1;
    159         if(judge(mid)){ans=mid;l=mid+1;}
    160         else r=mid-1;
    161     }
    162     cout<<ans<<endl;
    163     return 0;
    164 }
    View Code

    T2:熟练剖分   

    概率期望不是DP

    值得一提的是,wq学长为我们证明了某种树DP复杂度(枚举深度,子树大小。。):设(x,y)表示树上的一对节点对,那么考虑每个节点的贡献,每个节点会被它的父链上的每个节点计算一次,所以每个节点被计算n次即总复杂度n×n。

    还有很重要的是,打成相加形式才是n^2,不然是n^3

    n^2

    复制代码
    1 for(int j=size[x];j>=0;j--)
    2         {
    3             for(int k=0;k<=min(j,size[y]);k++)
    4             {
    5                 f[x][j][1]=min(f[x][j][1],f[x][j-k][1]+f[y][k][1]);
    6                 f[x][j][0]=min(f[x][j][0],f[x][j-k][0]+min(f[y][k][0],f[y][k][1]));
    7             }
    8         }
    复制代码

    n^3

    复制代码
    1 for(int j=size[x];j>=0;j--)
    2         {
    3             for(int k=size[y];k>=0;k--)
    4             {
    5                 f[x][j+k][1]=min(f[x][j+k][1],f[x][j][1]+f[y][k][1]);
    6                 f[x][j+k][0]=min(f[x][j+k][0],f[x][j][0]+min(f[y][k][0],f[y][k][1]));
    7             }
    8         }
    复制代码

    这道题就是这一类

    AC代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<vector>
     4 #include<cstring>
     5 using namespace std;
     6 const int mod=1e9+7;
     7 int n,indu[3100],root;
     8 vector<int>son[3100];
     9 long long f[3100][3100],g[2][2][3100],dep[3100];
    10 long long pow(long long a,long long b){
    11     long long ans=1;
    12     a%=mod;
    13     while(b){
    14         if(b&1) ans=(ans*a)%mod;
    15         b>>=1;
    16         a=(a*a)%mod;
    17     }
    18     return ans%mod;
    19 }
    20 long long max(long long a,long long b){
    21     return a>b?a:b;
    22 }
    23 void dfs(int x){
    24     if(son[x].size()==0){
    25         f[x][0]=1;
    26         //printf("x=%d 代价=%d 方案数=%d
    ",x,0,f[x][0]);
    27         return;
    28     }
    29     for(int i=0;i<son[x].size();i++){
    30         dfs(son[x][i]);
    31         dep[x]=max(dep[x],dep[son[x][i]]+1);
    32     }
    33     memset(g,0,sizeof(g));
    34     for(int i=1;i<=dep[son[x][0]]+1;i++){
    35         g[0][0][i]=f[son[x][0]][i-1];
    36         g[0][1][i]=f[son[x][0]][i];
    37         //printf("g[%d][%d][%d]=%d g[%d][%d][%d]=%d
    ",0,0,i,g[0][0][i],0,1,i,g[0][1][i]);
    38     }
    39     g[0][1][0]=f[son[x][0]][0];
    40     int cur=0,upw=dep[son[x][0]]+1;
    41     for(int i=1;i<son[x].size();i++){
    42         memset(g[cur^1],0,sizeof(g[cur^1]));
    43         for(int j=0;j<=upw;j++){
    44             for(int k=0;k<=dep[son[x][i]];k++){
    45                 (g[cur^1][0][max(j,k+1)]+=g[cur][0][j]*f[son[x][i]][k]%mod)%=mod;
    46                 (g[cur^1][1][max(j,k+1)]+=g[cur][1][j]*f[son[x][i]][k]%mod)%=mod;
    47                 (g[cur^1][1][max(j,k)]+=g[cur][0][j]*f[son[x][i]][k]%mod)%=mod;
    48             }
    49         }
    50         upw=max(dep[son[x][i]]+1,upw);
    51         cur^=1;
    52     }
    53     memcpy(f[x],g[cur][1],sizeof(f[x]));
    54     //for(int i=0;i<=dep[x];i++) printf("x=%d 代价=%d 方案=%d
    ",x,i,f[x][i]);
    55 
    56 }
    57 int main(){
    58     scanf("%d",&n);
    59     int x,y;
    60     long long num=1;
    61     for(int i=1;i<=n;i++){
    62         scanf("%d",&x);
    63         for(int j=1;j<=x;j++){
    64             scanf("%d",&y);
    65             son[i].push_back(y);
    66             indu[y]++;
    67         }
    68         if(x) (num*=pow(x,mod-2)%mod)%=mod;
    69     }
    70     for(int i=1;i<=n;i++){
    71         if(indu[i]==0){
    72             root=i;
    73             break;
    74         }
    75     }
    76     dfs(root);
    77     long long sum=0;
    78     for(int i=1;i<=n;i++) sum=(sum+i*f[root][i]%mod)%mod;
    79     //cout<<sum<<" "<<num<<endl; 
    80     printf("%lld
    ",(sum%mod*num%mod)%mod);
    81 }
    View Code

    T3:建造游乐场     高难标记

    毒瘤题,码量极短,思维量极高23333333

    为了保证考试总结的完整性 我决定借用外力(粘贴题解)

       

    先不粘AC代码了(心虚)

    第四次

    T1 礼物:

    实际上是个及其简单的概率期望

    But....我经过一下午的钻研(死皮赖脸缠着学长)(以致学长无法吃鸡)才大致明白了

      f[i]=∑f[s]*p[j]+∑p[j]*f[i]+1 
    	因为设f[i]表示买到状态为i到最终状态的期望次数
    	那么那么f[i]是可以由他的下一个状态转移过来
    	即所有的f[s].如果按原有的逻辑顺序对于f[i]来说转移到f[s]的概率是显然的
    	但是因为是倒着推,很显然f[s]就应该累加到f[i]上

    所以:

    正向求概率,反向求期望!

     1 #include<cstdio>
     2 #include<iostream>
     3 #define MAXN 25
     4 using namespace std;
     5 double p[MAXN],f[1<<22],wp[MAXN];
     6 int w[MAXN];
     7 int main()
     8 {
     9     int n;long long ans1=0;
    10     scanf("%d",&n);
    11     int maxk=(1<<n)-1;
    12     for(int i=1;i<=n;i++)
    13     {
    14         scanf("%lf%d",&p[i],&w[i]);
    15         ans1+=w[i];
    16     }
    17     cout<<ans1<<endl;
    18     f[maxk]=0;
    19     for(int i=0;i<=maxk;i++)
    20     {
    21         int state=i;
    22         for(int j=1;j<=n;j++)
    23         {
    24             if((state&(1<<(j-1))))continue;
    25             wp[state]+=p[j];
    26         }
    27     }
    28     for(int i=maxk-1;i>=0;i--)
    29     {
    30         f[i]=1;
    31         for(int j=1;j<=n;j++)
    32         {
    33             if((i&(1<<(j-1))))continue;
    34             f[i]+=(f[i|(1<<(j-1))]*p[j]);
    35         }
    36         f[i]/=wp[i];
    37         //cout<<i<<' '<<f[i]<<endl;
    38     }
    39     printf("%.3lf",f[0]);
    40     return 0;
    41 }
    View Code

    T2:通讯

    Tarjan缩点+贪心板子题

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<queue>
      4 #include<cstring>
      5 #define LL long long
      6 #define mem(a) memset(a,0,sizeof(a))
      7 #define MAXN 200005
      8 #define LL long long
      9 using namespace std;
     10 struct node{
     11     LL to[MAXN],head[MAXN],w[MAXN],nxt[MAXN],d[MAXN],low[MAXN],dfn[MAXN],s[MAXN],top,tot,num,out[MAXN],n,m,c[MAXN];
     12     LL To[MAXN],Head[MAXN],W[MAXN],Nxt[MAXN],cnt,Cnt,ans;
     13     bool in_s[MAXN];
     14     void clear()
     15     {
     16         mem(head);mem(Head);cnt=Cnt=ans=tot=top=num=0;mem(in_s);mem(dfn);
     17     }
     18     void add(LL u,LL v,LL val)
     19     {
     20         to[++cnt]=v;
     21         nxt[cnt]=head[u];
     22         w[cnt]=val;
     23         head[u]=cnt;
     24         return ;
     25     }
     26     void Add(LL u,LL v,LL val)
     27     {
     28         To[++Cnt]=v;
     29         Nxt[Cnt]=Head[u];
     30         W[Cnt]=val;
     31         Head[u]=Cnt;
     32         return ;
     33     }
     34     void Tarjan(LL x)
     35     {
     36         dfn[x]=low[x]=++tot;
     37         s[++top]=x;
     38         in_s[x]=1;
     39         for(LL i=head[x];i;i=nxt[i])
     40         {
     41             LL y=to[i];
     42             if(!dfn[y])
     43             {
     44                 Tarjan(y);
     45                 low[x]=min(low[x],low[y]);
     46             }
     47             else if(in_s[y])
     48             {
     49                 low[x]=min(low[x],dfn[y]);
     50             }
     51         }
     52         if(low[x]==dfn[x])
     53         {
     54             num++;
     55             while(top)
     56             {
     57                 LL p=s[top--];
     58                 in_s[p]=0;
     59                 c[p]=num;
     60                 if(p==x)break;
     61             }
     62         }
     63     }
     64     void toposort()
     65     {
     66         queue<int>Q;
     67         memset(d,0x3f,sizeof(d));
     68         d[c[1]]=0;
     69         Q.push(c[1]);
     70         while(!Q.empty())
     71         {
     72             LL x=Q.front();Q.pop();
     73             for(LL i=Head[x];i;i=Nxt[i])
     74             {
     75                 LL y=To[i];
     76                 out[y]--;
     77                 if(W[i]<d[y])
     78                 {
     79                     d[y]=W[i];
     80                 }
     81                 if(!out[y])Q.push(y);
     82             }
     83         }
     84         return ;
     85     }
     86     void Build_new()
     87     {
     88         for(LL i=1;i<=n;i++)
     89             for(LL j=head[i];j;j=nxt[j])
     90             {
     91                 LL k=to[j];
     92                 if(c[i]!=c[k])
     93                 {
     94                     Add(c[i],c[k],w[j]);
     95                     out[c[k]]++;
     96                 }
     97             }
     98     }
     99     inline LL Rd()
    100     {
    101         register LL x=0;char c=getchar();
    102         while(c>'9'||c<'0')c=getchar();
    103         while(c<='9'&&c>='0'){x=x*10+c-'0';c=getchar();}
    104         return x;
    105     }
    106     void work()
    107     {
    108         while(1)
    109         {
    110             n=Rd(),m=Rd();
    111             if(n==0&&m==0)return ;
    112             clear();
    113             while(m--)
    114             {
    115                 LL a=Rd(),b=Rd(),c=Rd();
    116                 a++;b++;
    117                 add(a,b,c);
    118             }
    119             Tarjan(1);
    120             Build_new();
    121             toposort();
    122             for(LL i=1;i<=num;i++)ans+=d[i];
    123             cout<<ans<<endl;
    124         }
    125     }
    126 }E;
    127 int main()
    128 {
    129     E.work();
    130     return 0;
    131 }
    View Code

    T3:奇袭(我不会玩甘宁啊)     高难标记

    27分算法:维护前缀和扫描

    74分算法:维护最大最小值

    AC算法:分治

    这里写的详细!!!

    再次膜拜DeepinC

    AC代码:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #define MAXN 50005
     5 using namespace std;
     6 int ans;
     7 int w[MAXN],mi[MAXN],ma[MAXN],t[MAXN*2],n;
     8 inline int Rd()
     9 {
    10     int x=0;char c=getchar();
    11     while(c<'0'||c>'9')c=getchar();
    12     while(c>='0'&&c<='9'){x=x*10+c-48;c=getchar();}
    13     return x;
    14 }
    15 int solve(int l,int r)
    16 {
    17     if(l==r)return 1;
    18     int mid=l+r>>1;
    19     int lans=solve(l,mid),rans=solve(mid+1,r);
    20     ans=lans+rans;
    21     ma[mid]=mi[mid]=w[mid];
    22     ma[mid+1]=mi[mid+1]=w[mid+1];
    23     for(int i=mid-1;i>=l;i--)
    24     {
    25         ma[i]=max(w[i],ma[i+1]);
    26         mi[i]=min(w[i],mi[i+1]);
    27     }
    28     for(int i=mid+2;i<=r;i++)
    29     {
    30         ma[i]=max(ma[i-1],w[i]);
    31         mi[i]=min(mi[i-1],w[i]);
    32     }
    33     for(int i=mid;i>=l;i--)
    34     {
    35         int j=ma[i]-mi[i]+i;
    36         if(j>mid&&j<=r&&ma[j]<=ma[i]&&mi[j]>=mi[i])ans++;
    37     }
    38     for(int i=mid+1;i<=r;i++)
    39     {
    40         int j=i-ma[i]+mi[i];
    41         if(j<=mid&&j>=l&&ma[j]<=ma[i]&&mi[j]>=mi[i])ans++;
    42     }
    43     int head,tail;
    44     head=tail=mid+1;
    45     for(int i=mid;i>=l;i--)// maxn in left && minn in right    mi[j]<mi[i] && ma[j] <ma[i] 
    46     {
    47         while(ma[tail]<=ma[i]&&tail<=r){t[tail+mi[tail]]++;tail++;}
    48         while(mi[head]>=mi[i]&&head<=r){t[head+mi[head]]--;head++;}
    49         if(t[i+ma[i]]>0)ans+=t[i+ma[i]];
    50     }
    51     while(head<tail){t[head+mi[head]]--;head++;}    
    52     while(tail<head){t[tail+mi[tail]]++;tail++;}
    53     head=tail=mid;
    54     for(int i=mid+1;i<=r;i++)
    55     {
    56         while(ma[tail]<=ma[i]&&tail>=l){t[tail-mi[tail]+MAXN]++;tail--;}
    57         while(mi[head]>=mi[i]&&head>=l){t[head-mi[head]+MAXN]--;head--;}
    58         if(t[MAXN+i-ma[i]]>0)ans+=t[MAXN+i-ma[i]];
    59     }
    60     while(head>tail){t[head-mi[head]+MAXN]--;head--;}    
    61     while(tail>head){t[tail-mi[tail]+MAXN]++;tail--;}
    62     return ans;
    63 }
    64 int main()
    65 {
    66  //     freopen("da.in","r",stdin);
    67 //    freopen("my.out","w",stdout);
    68     n=Rd();
    69     for(int i=1;i<=n;i++)
    70     {
    71         int a=Rd(),b=Rd();
    72         w[a]=b;
    73     }
    74     printf("%d
    ",solve(1,n));
    75     return 0;
    76 }
    77 /*
    78 8
    79 1 2
    80 2 6
    81 3 1
    82 4 7
    83 5 3
    84 6 5
    85 7 4
    86 8 8
    87 */
    View Code

    第五次

    T1:星际旅行

    考试想到正解,没有判连通

    AC代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<vector>
     5 using namespace std;
     6 const long long MAXN=200005;
     7 long long n,m,out[MAXN],s[MAXN],t[MAXN],add,addy;
     8 long long C[MAXN][3];
     9 long long ans;
    10 int f[MAXN],siz[MAXN];
    11 bool vst[MAXN];
    12 inline long long Rd()
    13 {
    14     register long long x=0;
    15     char c=getchar();
    16     while(c>'9'||c<'0')c=getchar();
    17     while(c>='0'&&c<='9'){x=x*10+c-48;c=getchar();}
    18     return x;
    19 }
    20 int Get(int a)
    21 {
    22     return f[a]==a?a:f[a]=Get(f[a]);
    23 }
    24 void un_ion(int a,int b)
    25 {
    26     int fa=Get(a),fb=Get(b);
    27     f[fa]=fb;
    28     siz[fb]+=siz[fa];
    29 }
    30 int main()
    31 {
    32 //    freopen("out.in","r",stdin);
    33 //    freopen("a.txt","w",stdout);
    34     n=Rd();m=Rd();
    35     for(int i=1;i<=n;i++)f[i]=i,siz[i]=1;
    36     for(long long i=1;i<=m;i++)
    37     {
    38         s[i]=Rd();t[i]=Rd();
    39         vst[s[i]]=vst[t[i]]=1;
    40         if(Get(s[i])!=Get(t[i]))un_ion(s[i],t[i]);
    41         if(s[i]==t[i]){add++;ans+=m-add;}
    42         else {out[s[i]]++;out[t[i]]++;addy++;}
    43     }
    44     int xup=0;
    45     for(int i=1;i<=n;i++)if(!vst[i])xup++;
    46     for(int i=1;i<=n;i++)
    47         if(vst[i]&&siz[Get(i)]!=n-xup){cout<<0<<endl;return 0;}
    48         else if(vst[i]) break;
    49     C[1][0]=C[1][1]=1;
    50     for(long long i=2;i<=m;i++)
    51     {
    52         C[i][0]=1;
    53         for(long long j=1;j<=2;j++)
    54             C[i][j]=C[i-1][j-1]+C[i-1][j];
    55     }
    56     for(long long i=1;i<=n;i++)
    57         ans+=C[out[i]][2];
    58     cout<<ans<<endl;
    59     return 0;
    60 }
    View Code

    T2:砍树

    数论分块。

    显然:

    辣么移项后易得:(本博猪没有图,自行脑补)。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<vector>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 int n;
     8 long long m,a[110],maxn;
     9 vector<long long>ok;
    10 int judge(long long x){
    11     long long len=0;
    12     for(int i=1;i<=n;i++){
    13         int g=ceil((double)a[i]/(double)x);
    14         len+=(long long)g;
    15     }
    16     //cout<<x<<" "<<len<<endl;
    17     if(x<=m/len) return 1;
    18     return 0;
    19 }
    20 int main(){
    21     scanf("%d%lld",&n,&m);
    22     for(int i=1;i<=n;i++) scanf("%lld",&a[i]),m+=a[i],maxn=max(a[i],maxn);
    23 //    cout<<"fsdf"<<endl;
    24     //maxn=1000000;
    25     for(long long i=1;i<=m;i++){
    26         long long sg=0;
    27         for(int j=1;j<=n;j++){
    28             sg+=ceil((double)a[j]/(double)i);
    29         }
    30         //cout<<i<<" "<<sg<<endl;
    31         long long sb=m/sg;
    32         //cout<<sb<<endl;
    33         ok.push_back(sb);
    34         i=m/(m/i);
    35     }
    36     long long ans=0;
    37     sort(ok.begin(),ok.end());
    38     for(int i=ok.size()-1;i>=0;i--){
    39     //    cout<<ok[i]<<endl;
    40         if(judge(ok[i])){
    41             ans=ok[i];
    42             break;
    43         }
    44     }
    45     printf("%lld
    ",ans);
    46 }
    View Code

    T3:超级树

    再次借用wd大佬题解

    AC代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #define LL long long
     4 #define MAXN 305
     5 using namespace std;
     6 LL dp[MAXN][MAXN],siz[MAXN];
     7 int main()
     8 {
     9     LL k,mod;
    10     scanf("%lld%lld",&k,&mod);
    11     dp[1][1]=dp[1][0]=1;
    12     siz[1]=1;
    13     for(int i=2;i<=k;i++)
    14     {
    15         if(siz[i-1]<k)siz[i]=siz[i-1]+siz[i-1]+1;
    16         else siz[i]=k+1;
    17         for(int l=0;l<=min(k,siz[i-1]);l++)
    18             for(int r=0;r<=min(k,siz[i-1]);r++)
    19             {
    20                 if(l+r>k)break;
    21                 LL num=dp[i-1][l]*dp[i-1][r]%mod;
    22                 if(!num)continue;
    23                 dp[i][l+r]+=num;if(dp[i][l+r]>=mod)dp[i][l+r]-=mod;
    24                 dp[i][l+r+1]+=num;if(dp[i][l+r+1]>=mod)dp[i][l+r+1]-=mod;
    25                 (dp[i][l+r]+=num*(l+r)*2)%=mod;
    26                 if(l+r>0)
    27                 (dp[i][l+r-1]+=num*l*r*2)%=mod;
    28                 if(l+r>0)
    29                 (dp[i][l+r-1]+=num*(l*(l-1)+r*(r-1)))%=mod;
    30             }
    31     }
    32     cout<<dp[k][1]%mod<<endl;
    33     return 0;
    34 }
    View Code
  • 相关阅读:
    JavaScript 入门之常见对象
    JavaScript 快速入门
    高级程序设计语言的共性内容
    CSS 快速入门
    HTML 快速入门
    正则表达式
    Oracle 11g安装
    部分框架结构图
    java定时器
    java垃圾回收机制的使用
  • 原文地址:https://www.cnblogs.com/hzoi-kx/p/11217629.html
Copyright © 2020-2023  润新知