【codeforces 732E】【贪心 map乱搞】

传送门:http://codeforces.com/contest/732/problem/E

描述:

E. Sockets
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

The ICM ACPC World Finals is coming! Unfortunately, the organizers of the competition were so busy preparing tasks that totally missed an important technical point — the organization of electricity supplement for all the participants workstations.

There are n computers for participants, the i-th of which has power equal to positive integer pi. At the same time there are m sockets available, the j-th of which has power euqal to positive integer sj. It is possible to connect the i-th computer to the j-th socket if and only if their powers are the same: pi = sj. It is allowed to connect no more than one computer to one socket. Thus, if the powers of all computers and sockets are distinct, then no computer can be connected to any of the sockets.

In order to fix the situation professor Puch Williams urgently ordered a wagon of adapters — power splitters. Each adapter has one plug and one socket with a voltage divider between them. After plugging an adapter to a socket with power x, the power on the adapter's socket becomes equal to , it means that it is equal to the socket's power divided by two with rounding up, for example  and .

Each adapter can be used only once. It is possible to connect several adapters in a chain plugging the first to a socket. For example, if two adapters are plugged one after enother to a socket with power 10, it becomes possible to connect one computer with power 3 to this socket.

The organizers should install adapters so that it will be possible to supply with electricity the maximum number of computers c at the same time. If there are several possible connection configurations, they want to find the one that uses the minimum number of adapters uto connect c computers.

Help organizers calculate the maximum number of connected computers c and the minimum number of adapters u needed for this.

The wagon of adapters contains enough of them to do the task. It is guaranteed that it's possible to connect at least one computer.

Input

The first line contains two integers n and m (1 ≤ n, m ≤ 200 000) — the number of computers and the number of sockets.

The second line contains n integers p1, p2, ..., pn (1 ≤ pi ≤ 109) — the powers of the computers.

The third line contains m integers s1, s2, ..., sm (1 ≤ si ≤ 109) — the power of the sockets.

Output

In the first line print two numbers c and u — the maximum number of computers which can at the same time be connected to electricity and the minimum number of adapters needed to connect c computers.

In the second line print m integers a1, a2, ..., am (0 ≤ ai ≤ 109), where ai equals the number of adapters orginizers need to plug into thei-th socket. The sum of all ai should be equal to u.

In third line print n integers b1, b2, ..., bn (0 ≤ bi ≤ m), where the bj-th equals the number of the socket which the j-th computer should be connected to. bj = 0 means that the j-th computer should not be connected to any socket. All bj that are different from 0 should be distinct. The power of the j-th computer should be equal to the power of the socket bj after plugging in abj adapters. The number of non-zero bj should be equal to c.

If there are multiple answers, print any of them.

Examples
input
2 2
1 1
2 2
output
2 2
1 1
1 2
input
2 1
2 100
99
output
1 6
6
1 0


题意:

给出n个电脑,m个电源,电脑有一个值ai,电源有一个值bi,电脑和电源能够配对当且仅当ai=bi。有无穷多个适配器,每对电源用一个适配器bi就减少一半(向上取整)。一个电源可以用很多次适配器。求最多配对多少电脑和电源,以及在最多配对下用的最少的适配器。还要输出方案。


思路:

将电源按照从小到大依次尝试和电脑配对,如果能够配对成功就配对。可以反证,假设按照这个顺序配对会使得配对数减少,也就是说有一个比他大的电源本应该和这个电脑相配。因为这两个电源都匹配到了这个电脑,所以当前枚举的电源往下能够匹配的电脑也能被那个比他大的电源匹配掉。
那么这样贪心会不会使得适配器数量不是最佳呢?容易证明是最少的。因为如果有多个值一样的电脑需要匹配当然优选电源小的来匹配(等值的电脑顺序任意),如果本来就只能配对这一个电脑,显然用较小的电源是最优的。


代码:

#include <bits/stdc++.h>
using  namespace  std;
#define rep(i,k,n) for(int i=k;i<=n;i++)

template<class T> T sqr(T x){ return x * x; }
template<class T> T gcd(T a, T b){ return b ? gcd(b, a%b) : a; }
template<class T> void read(T&num) {
    char CH; bool F=false;
    for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
    for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
    F && (num=-num);
}

const int N=2e5+10;

struct node{
 int num, id;
 node(){}
 node(int nu, int i): num(nu), id(i) {}
 bool operator < (const node& tmp)const{
   if(num != tmp.num)return num < tmp.num;
   return id < tmp.id;
 } 
}p[N], s[N];
std::map<int, int> mp;//计算机值出现的次数
int a[N], b[N], c, u;

int  main(){
  int n, m;
  read(n), read(m);
  rep(i, 1, n){
    read(p[i].num);
    p[i].id = i;
    mp[p[i].num]++;
  } 
  sort(p + 1, p + n + 1);
  rep(i, 1, m){
    read(s[i].num);
    s[i].id = i;
  }
  sort(s + 1, s + m + 1);
  
  rep(i, 1, m){
    rep(j, 0, 30){
      if(mp.count(s[i].num)){//发现可能匹配
        int t = lower_bound(p + 1, p + n + 1, node(s[i].num, 0)) - p +mp[s[i].num] - 1;
        //找到位置(由于有可能有多个相同的值,这里先从最后一个开始往前推)
        if(p[t].num == s[i].num && !b[p[t].id]){//
          b[p[t].id] = s[i].id; //电脑匹配到的socket
          mp[s[i].num]--;//数量-1
          a[s[i].id] = j; //对应的socket需要多少adapters
          u += j;
          c++;
          break;
        }
      }
      s[i].num = (s[i].num + 1) >> 1;
    }
  }
  printf("%d %d\n", c, u);
  rep(i, 1, m)printf("%d%c", a[i], i == m ? '\n':' ');
  rep(i, 1, n)printf("%d%c", b[i], i == n ? '\n':' ');
  return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值