HDU 3758

来源:互联网 发布:php 通用表单 编辑:程序博客网 时间:2024/06/06 21:05

n! 拆分因子比较好的方法。

二分可行最大值。

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <queue>using namespace std;typedef long long ll;typedef pair<int,int> pii;#define rep(i , n) for(int i = 0 ;i<(int)n;i++)#define rep1(i,x,y) for(int i = (int)x ; i<=(int)y;i++)const int N = 10100;int M = 1359;int vis[N], pos[N];vector<int> pri;void init(){    memset(vis,0,sizeof(vis));    for(int i =2 ; i<N; i++) if(!vis[i])            for(int j = i ; j < N ; j+=i)                vis[j] = i;    for(int i =2 ; i<N ; i++)    {        if(vis[i] == i)        {            pri.push_back(i);            pos[i] = pri.size() - 1;        }    }    M = pri.size();}int a[N] , b[N];int cal(int f , int n){    for(int i = 1; i <= n; i++)    {        for(int j = 0; j < M; j++)        {            int tn = b[i];            if(tn < pri[j]) break;            while(tn)            {                a[j] += (tn / pri[j]) * f;                tn /= pri[j];                if(a[j] < 0) return 0;            }        }    }    return 1;}int n,m;int ans[N][2] , tag = 0;bool judge(int x){    for(int j = 0; j < M; j++)    {        b[j] = 0;        int tn = x;        if(tn < pri[j]) break;        while(tn)        {            b[j] += (tn / pri[j]);            tn /= pri[j];        }        if(a[j] < b[j]) return 0;    }    return 1;}int c[N];void get2(int u){    int min_ = 1e9 ;    for(int i = 0; i<M ; i++)    {        c[i] = 0;        int x = u , p = pri[i];        if(x < p) break;        while(x)        {            c[i] += x / p;            x /= p;        }        min_ = min(min_ , a[i] / c[i]);    }    for(int i = 0 ; i<M ; i++)    {        if(pri[i] > u) break;        a[i] -= c[i] * min_;    }    ans[tag][0] = u;    ans[tag][1] = min_;    ++tag;}void get(){    int cnt = 0 ;    for(; a[0] > 0;)    {        int x = 2 , y = 10007;        while(x < y)        {            int mid = (x + y)>>1;            if(judge(mid)) x = mid + 1;            else y = mid;        }        get2(x - 1);    }}int main(){    init();    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d %d",&n , &m);        memset(a , 0 , sizeof(a));        memset(b , 0 , sizeof(b));        rep1(i , 1 , n){            scanf("%d",&b[i]);        }        cal(1 , n);        memset(b , 0 , sizeof(b));        rep1(i , 1 , m)        {            scanf("%d",&b[i]);        }        if(cal(-1 , m) == 0)        {            printf("-1\n");            continue;        }        tag = 0;        get();        printf("%d\n",tag);        for(int i = 0 ; i<tag ; i++)        {            printf("%d %d\n",ans[i][0] , ans[i][1]);        }    }    return 0;}/*9911100001*/


0 0
原创粉丝点击