UVA 1635 Irrelevant Elements

这个题 需要优化。 否则会超时。 C(m,n) 只能算一半。 另一半 用 减法 直接减掉。


刘汝佳P321 的书上写的公式要看懂。


意思就是  要使系数 能整出 m  那么  这个系数的 唯一分解式的 指数 要 大于等于  m的 唯一分解式的 指数 


举个例子。   如果 二项式的 系数为 6 那么唯一分解式 2 的指数为 1  3的指数为1  m 如果为12  2 的指数为 2  3的指数为1  m的 2,3的指数 都大于6 的指数


所以一定可以整除。  还有一个问题。 如果  m很大的话 就输出0.  注意后面 多个空行 因为有0个元素 什么都不输出 一个空行。


#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <string>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <cctype>
using namespace std;
#define ll long long
typedef unsigned long long ull;
#define maxn 100000+100
#define INF 1<<30
map <int, int> vis;
int s[maxn];
int m,n;
vector <int> q;
int res_m(){
    int x = m;
    for(int i = 2; i <= sqrt(x); i++){
        if(m == 1)
        break;
        if(m % i == 0){
            int tot = 0;
            while(m % i == 0){
                m /= i;
                tot++;
            }
            vis[i] = tot;
            q.push_back(i);
        }
    }
    if(m > 1){
        if(!vis.count(m)){
            q.push_back(m);
            vis[m] = 1;
        }
        else
            vis[m] = 1;
    }
}
int res(int k,int pan){
    int x = k;
    for(int j = 2; j <= sqrt(x); j++){
        if(k == 1)
        break;
        if(k % j == 0){
            int tot = 0;
            while(k % j == 0){
                k /= j;
                tot++;
            }
            s[j] += tot*pan;
        }
    }
    if(k > 1)
        s[k] += pan;
}
int main (){
    while(scanf("%d%d",&n,&m) != EOF){
        n --;
        memset(s,0,sizeof(s));
        q.clear();
        vis.clear();
        vector <int> path;
        res_m();
        if(q[q.size() - 1] >= 100000) {
            printf("0\n\n");
            continue;
        }
        res(n,1);
        int flag = 1;
        int len = q.size();
        for(int j = 0; j < len; j++){
            if(vis[q[j]] > s[q[j]]){
                flag = 0;
                break;
            }
        }
        set <int> biao;
        if(flag){
            path.push_back(2);
            biao.insert(2);
            if(!biao.count(n))
                path.push_back(n);
        }
        for(int i = 2; i <= n/2; i++){
            res(i,-1);
            res(n - i + 1,1);
            int flag = 1;
            for(int j = 0; j < len; j++){
                if(vis[q[j]] > s[q[j]]){
                    flag = 0;
                    break;
                }
            }
            if(flag){
                path.push_back(i+1);
                biao.insert(i+1);
                if(!biao.count(n-i+1))
                    path.push_back(n-i+1);
            }
        }
        sort(path.begin(),path.end());
        int len1 = path.size();
        printf("%d\n",len1);
        for(int i = 0; i < len1; i++){
            if(i == 0) printf("%d",path[i]);
            else printf(" %d",path[i]);
        }
        printf("\n");
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值