• [BZOJ1220][POJ1091][HNOI2002]跳蚤


    [BZOJ1220][POJ1091][HNOI2002]跳蚤

    试题描述

    Z城市居住着很多只跳蚤。在Z城市周六生活频道有一个娱乐节目。一只跳蚤将被请上一个高空钢丝的正中央。钢丝很长,可以看作是无限长。节目主持人会给该跳蚤发一张卡片。卡片上写有N+1个自然数。其中最后一个是M,而前N个数都不超过M,卡片上允许有相同的数字。跳蚤每次可以从卡片上任意选择一个自然数S,然后向左,或向右跳S个单位长度。而他最终的任务是跳到距离他左边一个单位长度的地方,并捡起位于那里的礼物。比如当N=2,M=18时,持有卡片(10, 15, 18)的跳蚤,就可以完成任务:他可以先向左跳10个单位长度,然后再连向左跳3次,每次15个单位长度,最后再向右连跳3次,每次18个单位长度。而持有卡片(12, 15, 18)的跳蚤,则怎么也不可能跳到距他左边一个单位长度的地方。当确定N和M后,显然一共有MN张不同的卡片。现在的问题是,在这所有的卡片中,有多少张可以完成任务。

    输入

    输入文件有且仅有一行,包括用空格分开的两个整数N和M。

    输出

    输出文件有且仅有一行,即可以完成任务的卡片数。 1≤M≤10^8,1≤N≤M,且M^N≤10^16。(注意:这个数据范围是错的,此题需要高精度。)

    输入示例

    2 4

    输出示例

    12

    数据规模及约定

    此题需要高精度!(POJ 上的不用,HNOI2002 原题也不用)

    题解

    其实就是找 N+1 个数互质的方案数,注意到最后一个数是固定的 M,所以可以给它分解质因数,然后容斥一下。MN - 前 N 个数中含有 1 个 M 的质因子的方案数 + 前 N 个数中含有 2 个 M 的质因子的方案数 - ... = ans

    最后贴一个高精度模板,搞定。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <queue>
    #include <cstring>
    #include <string>
    #include <map>
    #include <set>
    using namespace std;
    
    const int BufferSize = 1 << 16;
    char buffer[BufferSize], *Head, *Tail;
    inline char Getchar() {
        if(Head == Tail) {
            int l = fread(buffer, 1, BufferSize, stdin);
            Tail = (Head = buffer) + l;
        }
        return *Head++;
    }
    int read() {
        int x = 0, f = 1; char c = getchar();
        while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
        while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
        return x * f;
    }
    
    #define MAXN 1000+10
    struct bign  
    {  
        int len, s[MAXN];  
        bign ()  
        {  
            memset(s, 0, sizeof(s));  
            len = 1;  
        }  
        bign (int num) { *this = num; }  
        bign (const char *num) { *this = num; }  
        bign operator = (const int num)  
        {  
            char s[MAXN];  
            sprintf(s, "%d", num);  
            *this = s;  
            return *this;  
        }  
        bign operator = (const char *num)  
        {  
            for(int i = 0; num[i] == '0'; num++) ;  //去前导0  
            len = strlen(num);  
            for(int i = 0; i < len; i++) s[i] = num[len-i-1] - '0';  
            return *this;  
        }  
        bign operator + (const bign &b) const //+  
        {  
            bign c;  
            c.len = 0;  
            for(int i = 0, g = 0; g || i < max(len, b.len); i++)  
            {  
                int x = g;  
                if(i < len) x += s[i];  
                if(i < b.len) x += b.s[i];  
                c.s[c.len++] = x % 10;  
                g = x / 10;  
            }  
            return c;  
        }  
        bign operator += (const bign &b)  
        {  
            *this = *this + b;  
            return *this;  
        }  
        void clean()  
        {  
            while(len > 1 && !s[len-1]) len--;  
        }  
        bign operator * (const bign &b) //*  
        {  
            bign c;  
            c.len = len + b.len;  
            for(int i = 0; i < len; i++)  
            {  
                for(int j = 0; j < b.len; j++)  
                {  
                    c.s[i+j] += s[i] * b.s[j];  
                }  
            }  
            for(int i = 0; i < c.len; i++)  
            {  
                c.s[i+1] += c.s[i]/10;  
                c.s[i] %= 10;  
            }  
            c.clean();  
            return c;  
        }  
        bign operator *= (const bign &b)  
        {  
            *this = *this * b;  
            return *this;  
        }  
        bign operator - (const bign &b)  
        {  
            bign c;  
            c.len = 0;  
            for(int i = 0, g = 0; i < len; i++)  
            {  
                int x = s[i] - g;  
                if(i < b.len) x -= b.s[i];  
                if(x >= 0) g = 0;  
                else  
                {  
                    g = 1;  
                    x += 10;  
                }  
                c.s[c.len++] = x;  
            }  
            c.clean();  
            return c;  
        }  
        bign operator -= (const bign &b)  
        {  
            *this = *this - b;  
            return *this;  
        }  
        bign operator / (const bign &b)  
        {  
            bign c, f = 0;  
            for(int i = len-1; i >= 0; i--)  
            {  
                f = f*10;  
                f.s[0] = s[i];  
                while(f >= b)  
                {  
                    f -= b;  
                    c.s[i]++;  
                }  
            }  
            c.len = len;  
            c.clean();  
            return c;  
        }  
        bign operator /= (const bign &b)  
        {  
            *this  = *this / b;  
            return *this;  
        }  
        bign operator % (const bign &b)  
        {  
            bign r = *this / b;  
            r = *this - r*b;  
            return r;  
        }  
        bign operator %= (const bign &b)  
        {  
            *this = *this % b;  
            return *this;  
        }  
        bool operator < (const bign &b)  
        {  
            if(len != b.len) return len < b.len;  
            for(int i = len-1; i >= 0; i--)  
            {  
                if(s[i] != b.s[i]) return s[i] < b.s[i];  
            }  
            return false;  
        }  
        bool operator > (const bign &b)  
        {  
            if(len != b.len) return len > b.len;  
            for(int i = len-1; i >= 0; i--)  
            {  
                if(s[i] != b.s[i]) return s[i] > b.s[i];  
            }  
            return false;  
        }  
        bool operator == (const bign &b)  
        {  
            return !(*this > b) && !(*this < b);  
        }  
        bool operator != (const bign &b)  
        {  
            return !(*this == b);  
        }  
        bool operator <= (const bign &b)  
        {  
            return *this < b || *this == b;  
        }  
        bool operator >= (const bign &b)  
        {  
            return *this > b || *this == b;  
        }  
        string str() const  
        {  
            string res = "";  
            for(int i = 0; i < len; i++) res = char(s[i]+'0') + res;  
            return res;  
        }
    };
    
    istream& operator >> (istream &in, bign &x)  
    {  
        string s;  
        in >> s;  
        x = s.c_str();  
        return in;  
    }  
      
    ostream& operator << (ostream &out, const bign &x)  
    {  
        out << x.str();  
        return out;  
    }
    
    #define maxn 50
    #define LL bign
    int n, m;
    
    int prime[maxn], cnt;
    void getprime(int x) {
    	int t = sqrt(x + .5);
    	for(int i = 2; i <= t; i++) if(x % i == 0) {
    		prime[++cnt] = i;
    		while(x % i == 0) x /= i;
    	}
    	if(x > 1) prime[++cnt] = x;
    	return ;
    }
    
    LL Pow(LL a, int b) {
    	LL ans = 1, t = a;
    	while(b) {
    		if(b & 1) ans *= t;
    		t *= t; b >>= 1;
    	}
    	return ans;
    }
    
    int main() {
    	n = read(); m = read();
    	
    	getprime(m);
    	LL ans = Pow(m, n);
    	int all = (1 << cnt) - 1;
    	for(int i = 1; i <= all; i++) {
    		int tmp = 1; int c = 0;
    		for(int j = 1; j <= cnt; j++) if(i >> j - 1 & 1) tmp *= prime[j], c++;
    		LL tt = Pow(m / tmp, n);
    		if(c & 1) ans -= tt; else ans += tt;
    	}
    	
    	cout << ans << endl;
    	
    	return 0;
    }
    
  • 相关阅读:
    Python处理Excel文档(xlrd, xlwt, xlutils)
    张一鸣10年面试过2000人:混得好的年轻人都有这 5 种特质!
    PYTHON对文件及文件夹的一些操作
    ulipad 常用快捷键
    Python之re模块 —— 正则表达式操作
    Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)
    python 深入理解 赋值、引用、拷贝、作用域
    Python 模块学习:re模块
    [置顶] Android资源文件分析
    Tomcat 7最大并发连接数的正确修改方法
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/5808368.html
Copyright © 2020-2023  润新知