zoukankan      html  css  js  c++  java
  • The 2019 China Collegiate Programming Contest Harbin Site-----E、Exchanging Gifts

    题意:

    有n个序列(S_{i})
    有n行的输入,有两种操作可以得到(S_{i})
    1、 1 m (s_{i1}) (s_{i2}) …… (s_{im})
    2、 2 x y 表示这个数组由 第x和y的数组合并产生。
    问:最后得到的数组(S_{n}),在经过重新排列后,最多可以有几个元素和原本的(S_{n})不同。

    思路:

    首先我们看最后需要的答案,很显然,在重新排列后,如果这个数组中出现次数最多的元素的出现次数比原数组的长度的一半小,则答案就是原数组的长度。否则,答案就是(数组长度 - 重复次数)*2。

    方法1:
    我们需要看每个已知的数组对最终数组的贡献次数,就可以得到最终数组。要求贡献次数,直接从n~1枚举数组的贡献。在知道贡献次数以后,我们可以便利所有需要用到的数组,然后用map记录所有元素的个数。最后就可以求出最终数组中的元素总量和出现次数最多的数字的出现次数。既可求出答案(复杂度大于O(n),较慢)

    方法2:
    在求每个数组的贡献次数时,直接从n~1枚举数组的贡献,用一个O(n)求众数的方法求出数组中出现次数最多的元素的出现次数即可。(O(n))。

    此题最好用快读,否则容易tle。

    代码:

    方法1:

    //#include<bits/stdc++.h>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<vector>
    #include<stack>
    #include<bitset>
    #include<cstdlib>
    #include<cmath>
    #include<set>
    #include<list>
    #include<deque>
    #include<map>
    #include<queue>
    #define ll long long
    #define MOD 1000000007
    #define pdd pair<double,double>
    #define mem(a,x) memset(a,x,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0)
    using namespace std;
    const long long INF = 0x3f3f3f3f3f3f3f3fLL;
    const int inf = 0x3f3f3f3f;
    const double eps=1e-6;
    const int maxn=1000005; 
    inline char nc() {static char buf[1000000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;}
    inline void read(int &sum) {char ch=nc();sum=0;while(!(ch>='0'&&ch<='9')) ch=nc();while(ch>='0'&&ch<='9') sum=(sum<<3)+(sum<<1)+(ch-48),ch=nc();}
    
    int flag[maxn],in[maxn];
    bool vis[maxn];
    ll cnt[maxn];
    int n,m;
    vector<int>co[maxn];
    vector<int>G[maxn];
    map<int,ll>ans;
    queue<int>q;
    int op[maxn][3];
    void init()
    {
       for(int i=1;i<=n;i++){
          co[i].clear();
          G[i].clear();
          vis[i]=in[i]=cnt[i]=0;
          if(!q.empty())q.pop();
       }
       ans.clear();
    }
    void gao()
    {
        for(int i=n;i>=1;i--){
          if(flag[i]==2){
             cnt[op[i][1]]+=cnt[i];
             cnt[op[i][2]]+=cnt[i];
          }
        }
        for(int i=1;i<=n;i++){
           if(cnt[i]!=0&&flag[i]==1){
              for(auto j:co[i]){
                 ans[j]+=cnt[i];
              }
           }
        }
        ll sum=0,maxx=0;
        for(auto &i:ans){
            sum+=i.second;
            if(i.second>maxx)maxx=i.second;
        }
        if(maxx*2>=sum){
           printf("%lld
    ",(sum-maxx)*2);
        }else{
           printf("%lld
    ",sum);
        }
    }
    
    int main()
    {
       int T;
       IO;
       read(T);
       while(T--){
           read(n);
           init();
           for(int i=1;i<=n;i++){
              read(flag[i]);
              if(flag[i]==1){
                 read(m);
                 for(int j=1;j<=m;j++){
                     int x;
                     read(x);
                     co[i].push_back(x);
                 }
              }else{
                 read(op[i][1]);
                 read(op[i][2]);
              }
           }
           cnt[n]=1;
           gao();
       }
       return 0;
    }
     
    

    方法2:

    //#include<bits/stdc++.h>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<vector>
    #include<stack>
    #include<bitset>
    #include<cstdlib>
    #include<cmath>
    #include<set>
    #include<list>
    #include<deque>
    #include<map>
    #include<queue>
    #define ll long long
    #define MOD 1000000007
    #define pdd pair<double,double>
    #define mem(a,x) memset(a,x,sizeof(a))
    #define IO ios::sync_with_stdio(false);cin.tie(0)
    using namespace std;
    const long long INF = 0x3f3f3f3f3f3f3f3fLL;
    const int inf = 0x3f3f3f3f;
    const double eps=1e-6;
    const int maxn=1000005; 
    inline char nc() {static char buf[1000000],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;}
    inline void read(int &sum) {char ch=nc();sum=0;while(!(ch>='0'&&ch<='9')) ch=nc();while(ch>='0'&&ch<='9') sum=(sum<<3)+(sum<<1)+(ch-48),ch=nc();}
    
    int n,m;
    vector<int>co[maxn];
    ll cnt[maxn];
    int flag[maxn];
    int op[maxn][3];
    
    void solve()
    {
       cnt[n]=1;
       for(int i=n;i>=1;i--){
          if(flag[i]==2){
             cnt[op[i][1]]+=cnt[i];
             cnt[op[i][2]]+=cnt[i];
          }
       }
       //
       ll tot=0,val=0;
       ll all=0;
       for(int i=1;i<=n;i++){
           if(flag[i]==1&&cnt[i]>0){
              for(auto x:co[i]){
                 if(val==0){
                    tot+=cnt[i];
                    val=x;
                    continue;
                 }else if(val==x){
                    tot+=cnt[i];
                 }else{
                    tot-=cnt[i];
                    if(tot<0){
                       tot=-tot;
                       val=x;
                    }
                 }
              }
              all+=co[i].size()*cnt[i];
           }
       }
       tot=0;
       for(int i=1;i<=n;i++){
          if(cnt[i]>0&&flag[i]==1){
             for(auto v:co[i]){
                if(v==val)tot+=cnt[i];
             }
          }
          
       }
       //cout<<"aa"<<all<<" "<<tot<<endl;
       if(tot*2>=all){
          cout<<(all-tot)*2<<endl;
       }else{
          cout<<all<<endl;
       }
    }
    int main()
    {
       IO;
       int T;
       read(T);
       while(T--){
           read(n);
           for(int i=1;i<=n;i++){
               co[i].clear();
               cnt[i]=0;
               read(flag[i]);
               if(flag[i]==1){
                  read(m);
                  for(int j=1;j<=m;j++){
                     int x;
                     read(x);
                     co[i].push_back(x);
                  }
               }else{
                  read(op[i][1]);
                  read(op[i][2]);
               }
           }
           solve();
       }
       return 0;
    }
    
    越自律,越自由
  • 相关阅读:
    linux设置网关修改ip
    Linux Source命令及脚本的执行方式解析
    ARM9 S3C2440 定时器中断
    Linux下配置静态IP地址,设置DNS和主机名
    s3c2440外部中断操作
    vmware中为虚拟机添加硬盘空间
    『SHELL』SHELL脚本执行方式
    WCF开发的几个频骤
    MyEclipse下Axis2插件的下载和安装
    WCF系列(二) 使用配置文件构建和使用WCF服务
  • 原文地址:https://www.cnblogs.com/ha-chuochuo/p/13773639.html
Copyright © 2011-2022 走看看