zoukankan      html  css  js  c++  java
  • 记次浙大月赛 134

    链接

    虽做出的很少,也记录下来,留着以后来补。。浙大题目质量还是很高的

    B

    并查集的一些操作,同类和不同类我是根据到根节点距离的奇偶判断的,删点是直接新加一个点,记得福大月赛也做过类似的,并差集的这类关系题目还是比较常见的,有空深究一下。

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<stdlib.h>
     6 #include<vector>
     7 #include<cmath>
     8 #include<queue>
     9 #include<set>
    10 using namespace std;
    11 #define N 600010
    12 #define LL long long
    13 #define INF 0xfffffff
    14 const double eps = 1e-8;
    15 const double pi = acos(-1.0);
    16 const double inf = ~0u>>2;
    17 int fa[N],res[N],mp[N];
    18 int dis[N];
    19 int find(int x)
    20 {
    21     if(fa[x]!=x)
    22     {
    23         int ro = find(fa[x]);
    24         dis[x]+=dis[fa[x]];
    25         return fa[x] = ro;
    26     }
    27     else
    28     return x;
    29 }
    30 int main()
    31 {
    32     int n,m,i;
    33     char s[10];
    34     while(scanf("%d%d",&n,&m)!=EOF)
    35     {
    36         for(i = 1; i <= n+m; i++)
    37         {
    38             fa[i] = i;
    39             res[i] = 1;
    40             mp[i] = i;
    41             dis[i] = 0;
    42         }
    43         int g = n+1;
    44         while(m--)
    45         {
    46             int x,y;
    47             scanf("%s",s);
    48             if(s[0]=='L')
    49             {
    50                 scanf("%d%d",&x,&y);
    51                 x = mp[x];
    52                 y = mp[y];
    53                 int tx = find(x);
    54                 int ty = find(y);
    55                 if(tx!=ty)
    56                 {
    57                     fa[tx] = ty;
    58                     dis[tx] = (dis[x]+1+dis[y]);//合并时应根据两树上的节点距离来确定两树的根节点距离
    59                     res[ty]+=res[tx];
    60                 }
    61             }
    62             else if(s[0]=='Q')
    63             {
    64                 scanf("%d%d",&x,&y);
    65                 x = mp[x];
    66                 y = mp[y];
    67                 int tx = find(x);
    68                 int ty = find(y);
    69                 //cout<<tx<<" "<<ty<<endl;
    70                 if(tx!=ty)
    71                 {
    72                     printf("Unknown
    ");
    73                     continue;
    74                 }
    75                 if((dis[x]-dis[y])%2==0)
    76                 printf("Same
    ");
    77                 else
    78                 printf("Different
    ");
    79             }
    80             else if(s[0]=='S')
    81             {
    82                 scanf("%d",&x);
    83                 x = mp[x];
    84                 int tx = find(x);
    85                 printf("%d
    ",res[tx]);
    86             }
    87             else
    88             {
    89                 scanf("%d",&x);
    90                 int xx = mp[x];
    91                 int tx = find(xx);
    92                 res[tx]-=1;
    93                 mp[x] = ++g;
    94             }
    95         }
    96     }
    97     return 0;
    98 }
    View Code

    C

    离散化一下,枚举所有值所在的区间段,从左到右走一遍,采用边删边走的形式。

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<stdlib.h>
     6 #include<vector>
     7 #include<cmath>
     8 #include<queue>
     9 #include<set>
    10 #include<map>
    11 using namespace std;
    12 #define N 100010
    13 #define LL long long
    14 #define INF 0xfffffff
    15 const double eps = 1e-8;
    16 const double pi = acos(-1.0);
    17 const double inf = ~0u>>2;
    18 map<int,int>f;
    19 vector<int>ed[N];
    20 vector<int>dd[N];
    21 int c[N];
    22 int main()
    23 {
    24     int n,k,i,j;
    25     while(scanf("%d%d",&n,&k)!=EOF)
    26     {
    27         f.clear();
    28         int g = 0;
    29         for(i = 1; i <= n; i++)
    30         {
    31             ed[i].clear();
    32             dd[i].clear();
    33         }
    34         for(i = 1; i <=n ;i++)
    35         {
    36             scanf("%d",&c[i]);
    37             if(!f[c[i]]) f[c[i]] = ++g;
    38             if(i==1)
    39             {
    40                 dd[f[c[i]]].push_back(i);
    41                 continue;
    42             }
    43             int tg = f[c[i-1]];
    44             if(c[i]!=c[i-1])
    45             {
    46                 ed[tg].push_back(i-1);
    47                 dd[f[c[i]]].push_back(i);
    48             }
    49         }
    50         ed[f[c[n]]].push_back(n);
    51         int ans = 0;
    52         for(i = 1; i <= g; i++)
    53         {
    54             int tk = 0,st=0,ss=0;
    55             ss += ed[i][0]-dd[i][0]+1;
    56             ans =  max(ans,ss);
    57 
    58             for(j = 1 ;j < ed[i].size() ; j++)
    59             {
    60                 tk+=(dd[i][j]-ed[i][j-1]-1);
    61                 ss+=(ed[i][j]-dd[i][j]+1);
    62                 while(tk>k&&st<j)
    63                 {
    64                     tk-=(dd[i][st+1]-ed[i][st]-1);
    65                     ss-=(ed[i][st]-dd[i][st]+1);
    66                     st++;
    67                 }
    68 
    69                 ans = max(ans,ss);
    70             }
    71         }
    72         printf("%d
    ",ans);
    73     }
    74     return 0;
    75 }
    View Code

    F

    这题有点逗,看了半个多小时终于看懂了啥意思,然后。。一份更逗的AC代码,全部输出1.

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<stdlib.h>
     6 #include<vector>
     7 #include<cmath>
     8 #include<queue>
     9 #include<set>
    10 using namespace std;
    11 #define N 100000
    12 #define LL long long
    13 #define INF 0xfffffff
    14 const double eps = 1e-8;
    15 const double pi = acos(-1.0);
    16 const double inf = ~0u>>2;
    17 int main()
    18 {
    19     int t,b,e;
    20     cin>>t;
    21     while(t--)
    22     {
    23         cin>>b>>e;
    24         cout<<"1
    ";
    25     }
    26     return 0;
    27 }
    View Code

     补坑

    ----------------------------------------------------------

    D

    dp,今天周赛鹏队把月赛题放出来了,上面3个都A过了,就去看这题。

    这题着重点要放在有多少个不同的字母上面,用dp[i][g]表示有当前走了i步且有g个字母不同,往后递推步数,因为每次会变m个位置,那么可以枚举当前g个里面变了j个,那么len-g里面肯定要变m-j个。

    那么久可以写出递推方程dp[i-g+m-g][j] = dp[i][j]*C(g,j)*C(len-g,m-j) 注意下边界问题。

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<stdlib.h>
     6 #include<vector>
     7 #include<cmath>
     8 #include<queue>
     9 #include<set>
    10 using namespace std;
    11 #define N 101
    12 #define LL long long
    13 #define INF 0xfffffff
    14 #define mod 1000000009
    15 const double eps = 1e-8;
    16 const double pi = acos(-1.0);
    17 const double inf = ~0u>>2;
    18 char s1[N],s2[N];
    19 LL dp[N][N],c[N][N];
    20 void init()
    21 {
    22     for(int i=0;i<=100;i++)
    23         for(int j=0;j<=i;j++)
    24             if(!j || i==j)
    25                 c[i][j]=1;
    26             else
    27                 c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
    28 }
    29 int main()
    30 {
    31     int n,m,k,i,j,g;
    32     init();
    33     while(scanf("%d%d%d",&n,&k,&m)!=EOF)
    34     {
    35         memset(dp,0,sizeof(dp));
    36         cin>>s1>>s2;
    37         if(strlen(s1)!=strlen(s2)||strlen(s1)<m)
    38         {
    39             puts("0");
    40             continue;
    41         }
    42         int len = strlen(s1);
    43         int num = 0;
    44         for(i =0 ;i < len ; i++)
    45         if(s1[i]!=s2[i])
    46         num++;
    47         dp[0][num] = 1;
    48         for(i = 1; i <= k ; i++)
    49         {
    50             for(g = 0; g <= len; g++)
    51             for(j = 0 ; j <= min(g,m) ;j++)
    52             {
    53                 if(len-g<m-j) continue;
    54                // cout<<i<<" "<<j<<endl;
    55                 dp[i][g-j+(m-j)]=(dp[i][g-j+(m-j)]+((dp[i-1][g]*c[g][j])%mod*c[len-g][m-j])%mod)%mod;
    56 //                if(i==2&&j==0)
    57 //                {
    58 //                    cout<<c[num-g][m-j]<<" "<<num-g<<" "<<m-j<<endl;
    59 //                    cout<<i<<" "<<g-j+m-j<<" "<<dp[i][g-j+m-j]<<endl;
    60 //                }
    61             }
    62         }
    63         cout<<dp[k][0]<<endl;
    64     }
    65     return 0;
    66 }
    View Code

    H

    tarjan缩点,然后找一个最长路,这个可以用topo思想来找最长的。

      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<stdlib.h>
      6 #include<vector>
      7 #include<cmath>
      8 #include<queue>
      9 #include<set>
     10 #include<stack>
     11 using namespace std;
     12 #define N 100010
     13 #define LL long long
     14 #define INF 0xfffffff
     15 const double eps = 1e-8;
     16 const double pi = acos(-1.0);
     17 const double inf = ~0u>>2;
     18 vector<int>ed[N];
     19 vector<int>dd[2];
     20 vector<int>ee[N];
     21 int de[N],nn[N],dis[N];
     22 bool vis[N];
     23 int pre[N],lowlink[N],sccno[N],dfs_lock,scc_cnt;
     24 stack<int>S;
     25 void dfs(int u)
     26 {
     27     pre[u] = lowlink[u] = ++dfs_lock;
     28     S.push(u);
     29     for(int i = 0 ;i  < (int)ed[u].size() ; i++)
     30     {
     31         int v = ed[u][i];
     32         if(!pre[v])
     33         {
     34             dfs(v);
     35             lowlink[u] = min(lowlink[u],lowlink[v]);
     36         }
     37         else if(!sccno[v])
     38         lowlink[u] = min(lowlink[u],pre[v]);
     39     }
     40     if(lowlink[u]==pre[u])
     41     {
     42         scc_cnt++;
     43         int g = 0;
     44         for(;;)
     45         {
     46             int x = S.top();S.pop();
     47             sccno[x] = scc_cnt;
     48             g++;
     49             if(x==u) break;
     50         }
     51         nn[scc_cnt] = g;
     52     }
     53 }
     54 void find_scc(int n)
     55 {
     56     dfs_lock = scc_cnt = 0;
     57     memset(sccno,0,sizeof(sccno));
     58     memset(pre,0,sizeof(pre));
     59     for(int i = 0 ;i < n; i++)
     60     if(!pre[i]) dfs(i);
     61 }
     62 int find()
     63 {
     64     int i;
     65     for(i = 1 ;i <= scc_cnt ; i++)
     66         dis[i] = 0;
     67     queue<int>q;
     68     for(i = 1 ;i <= scc_cnt ; i++)
     69     {
     70         if(de[i]==0)
     71         {
     72             q.push(i);
     73             dis[i] = nn[i];
     74         }
     75     }
     76     while(!q.empty())
     77     {
     78         int tu = q.front();
     79         q.pop();
     80         for(i = 0; i < ee[tu].size() ; i++)
     81         {
     82             int v = ee[tu][i];
     83             dis[v] = max(dis[v],dis[tu]+nn[v]);
     84             de[v]--;
     85             if(de[v]==0)
     86                 q.push(v);
     87         }
     88     }
     89     int ans = 0;
     90     for(i = 1 ; i <= scc_cnt ; i++)
     91     ans = max(ans,dis[i]);
     92     return ans;
     93 }
     94 int main()
     95 {
     96     int i,m,n,j;
     97     while(scanf("%d%d",&n,&m)!=EOF)
     98     {
     99         memset(de,0,sizeof(de));
    100         for(i = 0 ;i <= n ;i++)
    101         {
    102             ed[i].clear();
    103             ee[i].clear();
    104         }
    105         dd[0].clear();
    106         dd[1].clear();
    107         for(i = 1; i <= m ;i++)
    108         {
    109             int u,v;
    110             scanf("%d%d",&u,&v);u--,v--;
    111             ed[u].push_back(v);
    112         }
    113         find_scc(n);
    114         for(i = 0; i < n ;i++)
    115         {
    116             for(j = 0;j < (int)ed[i].size() ; j++)
    117             {
    118                 int v = ed[i][j];
    119                 if(sccno[i]!=sccno[v])
    120                 {
    121                     vector<int>::iterator it;
    122                     int tu = sccno[i],tv = sccno[v];
    123 //                    it = lower_bound(ee[tu].begin(),ee[tu].end(),tv);
    124 //                    if(it==ee[tu].end()||(*it)!=tv)
    125 //                    {
    126                         ee[tu].push_back(tv);
    127                         de[tv]++;
    128 //                    }
    129                 }
    130             }
    131         }
    132         printf("%d
    ",find());
    133     }
    134     return 0;
    135 }
    View Code
  • 相关阅读:
    加解密工具类(含keystore导出pfx)
    Java使用数字证书加密通信(加解密/加签验签)
    关于javax.crypto.BadPaddingException: Blocktype错误的几种解决方法
    产生定长的随机数
    数字证书生成--加密密/加签验签
    随机指定范围内N个不重复的数
    sql2012还原sql2008备份文件语句
    uploadify API
    海量数据处理分析
    .net经验积累
  • 原文地址:https://www.cnblogs.com/shangyu/p/3763929.html
Copyright © 2011-2022 走看看