kuangbin 带你飞 数学基础

模版整理:

晒素数

void init()
{
    cas = 0;
    for (int i = 0 ; i < MAXD ; i++) is_prime[i] = true;
    is_prime[0] = is_prime[1] = false;
    for (int i = 2 ; i < MAXD ; i++)
    {
        if (is_prime[i])
        {
            prime[cas++] = i;
            for (int j = i + i ; j < MAXD ; j += i)
                is_prime[j] = false;
        }
    }
}

合数分解

int x = src[i];
            int cnt = 0,tot = 0;
            for (int j = 0 ; j < cas && prime[j] * prime[j] <= x ; j++)
            {
                if (x % prime[j] == 0)
                {
                    res[cnt++] = prime[j];
                    while (x % prime[j] == 0)
                    {
                        tot++;
                        x /= prime[j];
                    }
                }
            }
            if (x > 1)
            {
                res[cnt++] = x;
                tot++;
            }

大素数筛。1-2^31内某个长度小于10W的区间的素数个数

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 100000;
LL prime[MAXN / 10];
bool is_prime[MAXN + 10];
bool flag[MAXN + 10000] ;
int cas;

void init()
{
    for (int i = 0 ; i < MAXN ; i++) is_prime[i] = true;
    is_prime[0] = false;
    is_prime[1] = false;
    cas = 0;
    for (int i = 2 ; i < MAXN ; i++)
    {
        if (is_prime[i])
        {
            prime[cas++] = i;
            for (int j = i + i ; j < MAXN ; j += i)
                is_prime[j] = false;
        }
    }
}

int main()
{
    init();
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        LL a,b;
        scanf("%lld%lld",&a,&b);
        if (b <= 80000)
        {
            int cnt = 0;
            for (int i = a ; i <= b ; i++)
                if (is_prime[i]) cnt++;
            printf("Case %d: %d\n",kase++,cnt);
            continue;
        }
        else
        {
            if (a <= 2) a = 2;
            int sz = b - a;
            for (int i = 0 ; i <= sz ; i++) flag[i] = true;
            for (int i = 0 ; i < cas && prime[i] * prime[i] <= b ; i++)
            {
                int k = a / prime[i];
                if (k * prime[i] < a) k++;
                if (k <= 1) k++;
                while (k * prime[i] <= b)
                {
                    flag[k * prime[i] - a] = false;
                    k++;
                }
            }
            int cnt = 0;
            for (int i = 0 ; i <= sz ; i++)
                if (flag[i] == true) cnt++;
            printf("Case %d: %d\n",kase++,cnt);
        }
    }
    return 0;
}

判断1-N中5的因子的个数,可以将代码5改编

int cnt = 0;
    while (mid)
    {
        cnt += mid / 5;
        mid /= 5;
    }

中国剩余定理

LL china(int n,int *a,int *m)
{
        LL M = 1,d,y,x = 0;
        for (int i = 0 ; i < n ; i++) M *= m[i];
        for (int i = 0 ; i < n ; i++)
        {
                LL w = M / m[i];
                gcd(m[i],w,d,d,y);
                x = (x + y * w * a[i]) % M;
        }
        return (x + M) % M;
}

POJ 1061 青蛙的约会

欧几里德解方程

(y+nt)-(x+mt) = k * L;

(n - m)t + K‘L = x - y;

求最小正整数解

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
LL gcd(LL a, LL b) {return a % b == 0 ? b : gcd(b, a % b);}
LL ext_gcd(LL a,LL b,LL &x,LL &y)
{
    if (a == 0 && b == 0) return -1;
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    LL d = ext_gcd(b,a % b,y,x);
    y -= a / b * x;
    return d;
}
LL x,y,m,n,L;

int main()
{
    while (scanf("%I64d%I64d%I64d%I64d%I64d",&x,&y,&m,&n,&L) != EOF)
    {
        LL a = n - m, b = L, c = x - y;
        LL d = gcd(a,b);
        if (c % d != 0)
        {
            puts( "Impossible" );
            continue;
        }
        a /= d;
        b /= d;
        LL x,y;
        ext_gcd(a,b,x,y);
        //cout << a << " " << b << " " << x << " " << y << endl;
        x *= c / d;
        y *= c / d;
        //cout << y << endl;
        //cout << x << endl;
        LL  tmp = L / d;
        x = (x % tmp + tmp) % tmp;
        cout << x << endl;
    }
    return 0;
}

Light Oj 1370 Bi-shoe and Phi-shoe

题意:找到欧拉函数值大于对应数的最小欧拉函数的数

首先素数的欧拉函数值为对应数字减去1

对于任意X,X满足大于等于prime[i],小于等于prime[i + 1],那么这个区间内的所有数字的欧拉函数值都是小于等于

prime[i],那么若想找到欧拉函数大于X的那个值就是大于X的第一个素数

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
/*对任意x,有prime[i]<=x<prime[i+1]必定有EulerPhi[x]<=prime[i],
要满足phi(p)>=x那么p必定为x后面的第一个素数,进行素数打表即可。*/
const int MAXN = 3000010;
bool is_prime[MAXN];
void init()
{
    for (int i = 0 ; i < MAXN ; i++) is_prime[i] = true;
    is_prime[0] = is_prime[1] = false;
    for (int i = 2 ; i < MAXN ; i++)
    {
        if (is_prime[i])
        {
            for (int j = i + i ; j < MAXN ; j += i)
                is_prime[j] = false;
        }
    }
}

int main()
{
    init();
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        int n;
        scanf("%d",&n);
        LL sum = 0;
        for (int i = 1 ; i <= n ; i++)
        {
            int x;
            scanf("%d",&x);
            for (int j = x + 1 ; j < MAXN ; j++)
            {
                if (is_prime[j])
                {
                    sum += j;
                    break;
                }
            }
        }
        printf("Case %d: %lld Xukha\n",kase++,sum);
    }
    return 0;
}

Light Oj 1356 Prime Independence

题意:找到最大的子集使得子集内任何2个数之间都不是素数的倍数的关系

此题可以转换成最大独立集来求,不过好像直接用匈牙利算法会T,所以用HK算法

建图:X部为指数为奇数,Y部为指数为偶数,原音:同奇同偶必然不可能构成一个数是另一个数的素数倍数,

一个为奇数一个为偶数时可以试除一个素数看是否存在然后建图求最大独立集合

另外此题我一开始想简单部分奇部偶部来建图最后除以2.这样可能会T。

LightOj 1341 Aladdin and the Flying Carpet

给出整数 a 和 b ,求区间[b, a] 内的 a 的约数对的个数,a 的约数对(比如[2, 3] 与 [3, 2] 为同一对)。

合数分解后得出(a0 ^ p0) * (a1 ^ p1).....

那么约束对个数为(p0 + 1) * (p1 + 1) * (p2 + 1)......  / 2;

然后从1-B枚举判断A的因子对应减去

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 1000010;
bool is_prime[MAXN];
int cas,prime[MAXN];
LL a,b;

void init()
{
    cas = 0;
    for (int i = 0 ; i < MAXN ; i++) is_prime[i] = true;
    is_prime[0] = is_prime[1] = false;
    for (int i = 2 ; i < MAXN ; i++)
    {
        if (is_prime[i])
        {
            prime[cas++] = i;
            for (int j = i + i ; j < MAXN ; j += i)
                is_prime[j] = false;
        }
    }
}

int tot,cnt;
int num[MAXN],res[MAXN];

int main()
{
    init();
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%lld%lld",&a,&b);
        if (a <= b * b)
        {
            printf("Case %d: %d\n",kase++,0);
            continue;
        }
        tot = cnt = 0;
        LL x = a,sum = 1;
        int i = 0;
        while(prime[i] < x && i < cas)
        {
            int val = 0;
            if (x % prime[i] == 0)
            {
                while (x % prime[i] == 0)
                {
                    x /= prime[i];
                    val++;
                }
            }
            sum *= (val + 1);
            i++;
        }
        if (x > 1)
        {
            //res[cnt++] = x;
            sum *= 2;
        }
        //for (int i = 0 ; i < tot ; i++) sum *= (num[i] + 1);
        sum /= 2;
        for (int i = 1 ; i < b ; i++)
            if (a % i == 0) sum--;
        printf("Case %d: %lld\n",kase++,sum);
    }
    return 0;
}

Light Oj 1336 Sigma Function

定义f(x)为x的所有因子的和,计算H(x)表示从1到X中f(x)为偶数的数字的个数

首先一个数可以表示成(ao ^ p0) * (a1 ^ p1) *......

那么这个数的因子的个数可以表示成(a0 ^ 0 + a0 ^ 1 + ....a0 ^ p0) * (a1 ^ 0 + .... a1 ^ p1) * .....

可见如果为偶数条件很麻烦,如果为奇数那么就是这个所有乘积项全都为奇数

于是问题可以反向来解决,变为统计因子数目为奇数的个数

于是有几个条件第一:如果底数是2,那么这一项构成的乘积项必然是奇数

       第二:如果底数是奇数,那么只有当当前项的次数为偶数的时候该项为奇数

于是判断H(x)我们用二分来判断位置确定答案,对于f(x)为奇数利用DFS操作

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 1000010;
const LL INF = 1e12;
bool is_prime[MAXN];
int cas,prime[MAXN];
LL a,b;

void init()
{
    cas = 0;
    for (int i = 0 ; i < MAXN ; i++) is_prime[i] = true;
    is_prime[0] = is_prime[1] = false;
    for (int i = 2 ; i < MAXN ; i++)
    {
        if (is_prime[i])
        {
            prime[cas++] = i;
            for (int j = i + i ; j < MAXN ; j += i)
                is_prime[j] = false;
        }
    }
}

LL N;
LL val[1800000];
LL num;

void dfs(LL depth,LL sum)
{
    val[num++] = sum;
    if (depth >= cas) return;
    for (LL i = depth ; i < cas ; i++)
    {
        if (i == 0)
        {
            if(sum <= INF / 2) dfs(i,sum * 2LL);
            else return;
        }
        else
        {
            LL res = (LL)prime[i] * (LL)prime[i];
            if (sum <= INF / res) dfs(i,res * sum);
            else return;
        }
    }
}

LL calcu(LL N)
{
    int pos = upper_bound(val,val + num,N)- val;
    return pos;
}

int main()
{
    init();
    num = 0;
    dfs(0,1);
    sort(val,val + num);
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        LL N;
        scanf("%lld",&N);
        LL ret = calcu(N);
        printf("Case %d: %lld\n",kase++,N - ret);
    }
    return 0;
}

Light Oj 1282Leading and Trailing

求N的k次方的前三位和后三位

后三位就是简单的快速幂取模

前三位利用log来处理

N ^ k = 10 ^ T,这里T可以为小数,

可以变成10 ^ x * 10 ^ y;这里X表示整数部分,y表示小数部分,那么含义什么

x表示N^k的数字位数,y表示大小。那么实际上求前三位就是求y。

然后利用POW(10,y)进行相应的运算即可

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MOD = 1000;
LL pow_mod(LL val,LL cnt)
{
    LL ret = 1;
    while (cnt)
    {
        if (cnt & 1) ret = ret * val % MOD;
        val = val * val % MOD;
        cnt >>= 1;
    }
    return ret;
}

int main()
{
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        LL a,b;
        cin >> a >> b;
        double res = pow(10.0,fmod(b * log10(1.0 * a),1));
        printf("Case %d: %d %03lld\n",kase++,(int)(res * 100.0),pow_mod(a,b));
    }
    return 0;
}

LightOj 1259 Goldbach`s Conjecture

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 10000010;
bool is_prime[MAXN];
int prime[MAXN / 10],cas;
void init()
{
    cas = 0;
    for (int i = 0 ; i < MAXN ; i++) is_prime[i] = true;
    is_prime[0] = is_prime[1] = false;
    for (int i = 2 ; i < MAXN ; i++)
    {
        if (is_prime[i])
        {
            prime[cas++] = i;
            for (int j = i + i ; j < MAXN ; j += i)
                is_prime[j] = false;
        }
    }
}

int main()
{
    init();
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        int n;
        scanf("%d",&n);
        int ret = 0;
        for (int i = 0 ; i < cas && prime[i] <= n / 2 ; i++)
        {
            if (is_prime[n - prime[i]]) ret++;
        }
        printf("Case %d: %d\n",kase++,ret);
    }
    return 0;
}

LightOj 1245 Harmonic Number (II)

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
LL N;
int main()
{
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%lld",&N);
        LL ret = 0;
        for (LL i = 1 ; i <= sqrt(1.0 * N) ; i++)
            ret += N / i;
        for (LL i = 1 ; i <= sqrt(1.0 * N) ; i++)
            ret += (N / i - N / (i + 1)) * i;
        if (N / (LL)(sqrt(1.0 * N)) == (LL)sqrt(1.0 * N))
            ret -= (LL)sqrt(1.0 * N);
        printf("Case %d: %lld\n",kase++,ret);
    }
    return 0;
}

LightOj 1236 Pairs Forming LCM

求N2循环中LCM==N的个数

对于N合数分解有N = a1 ^ p1 * a2 ^ p2 * ....

对于i,j的LCM = N

那么有i = b1 ^ q1 * b2 ^ q2 * ......

   j = c1 ^ x1 * c2 ^ x2  * ......

于是有p1 = max(q1,x1)那么就得到答案了。就是qi,xi的组合方案数,另外注意循环的方式和重复计算

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 10000010;
bool is_prime[MAXN];
int prime[MAXN / 10];
int cas;

void init()
{
    cas = 0;
    for (int i = 0 ; i < MAXN ; i++) is_prime[i] = true;
    is_prime[0] = is_prime[1] = false;
    for (int i = 2 ; i < MAXN ; i++)
    {
        if (is_prime[i])
        {
            prime[cas++] = i;
            for (int j = i + i ; j < MAXN ; j += i)
                is_prime[j] = false;
        }
    }
}

int cnt,tot;
LL N;
int num[MAXN / 10];

int main()
{
    init();
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%lld",&N);
        LL x = N;
        tot = cnt = 0;
        LL sum = 1;
        for (int i = 0 ; i < cas && prime[i] <= x ; i++)
        {
            if (x % prime[i] == 0)
            {
                tot++;
                int val = 0;
                while (x % prime[i] == 0)
                {
                    val++;
                    x /= prime[i];
                }
                sum *= 2 * val + 1;
            }
        }
        if (x > 1)
        {
            sum *= 3;
            tot++;
        }
        sum = sum / 2 + 1;
        printf("Case %d: %lld\n",kase++,sum);
    }
    return 0;
}

LightOj 1234 Harmonic Number

计算1/1 + 1/2 + 1/3 + 1/4 + .......

这个题有三种处理方法

第一种如果直接开对应数组是开不下的,但是时间上是够的,于是可以适当优化空间,

所遇预先没50个存一组剩下的不满足50一组的直接暴力

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 1e8;
double ans[MAXN / 50 + 10];

void init()
{
    ans[0] = 0.0;
    double cur = 0.0;
    for (int i = 1 ; i <= MAXN ; i++)
    {
        cur += 1.0 / (double)i;
        if (i % 50 == 0) ans[i / 50] = cur;
    }
}

int main()
{
    init();
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        int N;
        scanf("%d",&N);
        int st = N / 50;
        double ret = ans[st];
        for (int i = st * 50 + 1 ; i <= N ; i++)
            ret += 1.0 / (double)i;
        printf("Case %d: %.10lf\n",kase++,ret);
    }
    return 0;
}

第二种是离线处理这个很好。

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const double eps = 1e-9;
const int MAXN = 10010;
struct node
{
    int idx,ask;
    double ans;
    friend bool operator < (const node &a,const node &b)
    {
        return a.ask < b.ask;
    }
}src[MAXN];

int cmp(const node&a,const node &b)
{
    return a.idx < b.idx;
}

int main()
{
    int T,kase = 1;
    scanf("%d",&T);
    for (int i = 1 ; i <= T ; i++) scanf("%d",&src[i].ask);
    for (int i = 1 ; i <= T ; i++) src[i].idx = i;
    sort(src + 1,src + 1 + T);
    double cur = 0.0;
    int step = 1;
    for (int i = 1 ; i <= 1e8 ; i++)
    {
        if (step > T) break;
        cur = cur + 1.0 / (double)i;
        while (src[step].ask == i)
        {
            src[step].ans = cur;
            step++;
        }
    }
    sort(src + 1,src + 1 + T ,cmp);
    for (int i = 1 ; i <= T ; i++)
    {
        printf("Case %d: %.10lf\n",kase++,src[i].ans + eps);
    }
    return 0;
}

第三个是神奇的数学结论

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 1000010;
double ret[MAXN];
#define gamma 0.57721566490153286060651209008240243104215933593992
int N;

int main()
{
    ret[0] = 0.0;
    for (int i = 1 ; i < MAXN ; i++) ret[i] = ret[i - 1] + 1.0 / (double)i;
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d",&N);
        printf("Case %d: ",kase++);
        if (N < MAXN) printf("%.10lf\n",ret[N]);
        else
        {
            printf("%.10lf\n",(log(N) + log(N + 1)) / 2 + gamma);
        }
    }
    return 0;
}

LightOj 1220 Mysterious Bacteria

求一个数最多是一个数的几次幂

合数分解次数求GCD

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 1000010;
const int INF = 0x3f3f3f3f;
bool is_prime[MAXN];
int cas,prime[MAXN];

void init()
{
    cas = 0;
    for (int i = 0 ; i < MAXN ; i++) is_prime[i] = true;
    is_prime[0] = is_prime[1] = false;
    for (int i = 2 ; i < MAXN ; i++)
    {
        if (is_prime[i])
        {
            prime[cas++] = i;
            for (int j = i + i ; j < MAXN ; j += i)
                is_prime[j] = false;
        }
    }
}

int main()
{
    init();
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        int val = 0;
        LL N;
        scanf("%lld",&N);
        LL x = N;
        if (x < 0LL) x = -x;
        for (int i = 0 ; i < cas && prime[i] <= x ; i++)
        {
            int cnt = 0;
            if (x % prime[i] == 0)
            {
                while (x % prime[i] == 0)
                {
                    cnt++;
                    x /= prime[i];
                }
                val = gcd(val,cnt);
            }
        }
        if (x > 1)
        {
            val = 1;
        }
        if (N < 0)
        {
            while (val % 2 == 0) val /= 2;
        }
        printf("Case %d: %d\n",kase++,val);
    }
    return 0;
}

LightOj 1214 Large Division

判断大数是不是能整除。一个是直接JAVA水,另一个利用同余定理做

JAVA:

import java.util.*;
import java.math.BigInteger;
import java.util.Scanner;

public class Main
{
    public static void main(String args[])
    {
        Scanner sc = new Scanner(System.in);
        BigInteger a,b,d;
        int T;
        T = sc.nextInt();
        int kase = 1;
        while (T-- != 0)
        {
            a = new BigInteger(sc.next());
            b = new BigInteger(sc.next());
            a = a.abs();
            b = b.abs();
            if (a.mod(b).equals(BigInteger.ZERO))
            {
                System.out.println("Case " + kase++ + ": divisible");
            }
            else
            {
                System.out.println("Case " + kase++ + ": not divisible");
            }
        }
    }
}

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 10010;
char str[MAXN];
LL m;

int main()
{
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%s%lld",str,&m);
        LL cur = 0;
        int len = strlen(str);
        for (int i = 0 ; i < len ; i++)
        {
            if (str[i] == ‘-‘) continue;
            cur = (cur * 10 + str[i] - ‘0‘) % m;
        }
        if (cur == 0) printf("Case %d: divisible\n",kase++);
        else printf("Case %d: not divisible\n",kase++);
    }
    return 0;
}

LightOj 1213 Fantasy of a Summation

利用简单的方法计算相应的代码

感觉这个题有点期望的意思

一共有N^K中组合,每种组合K个数字,平均分给N个数字,然后一直乘到一起

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 1010;
LL sum;
LL N,K,MOD;
LL src[MAXN];

LL pow_mod(LL x,int cnt)
{
    LL ret = 1;
    while (cnt)
    {
        if (cnt & 1) ret = ret * x % MOD;
        x = x * x % MOD;
        cnt >>= 1;
    }
    return ret;
}

int main()
{
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%lld%lld%lld",&N,&K,&MOD);
        for (int i = 1 ; i <= N ; i++)
            scanf("%lld",&src[i]);
        LL ret = 0;
        for (int i = 1 ; i <= N ; i++)
        {
            ret = (ret + src[i]) % MOD;
        }
        LL val = pow_mod(N,K - 1);
        printf("Case %d: %lld\n",kase++,ret * val % MOD * K % MOD);
    }
    return 0;
}

LightOj 1197 Help Hanzo

区间内素数的个数,大区间的。区间长度很少

大区间筛小区间的题目

利用预先筛根号N的素数然后做就行了。这个是个模版类的问题

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 100000;
LL prime[MAXN / 10];
bool is_prime[MAXN + 10];
bool flag[MAXN + 10000] ;
int cas;

void init()
{
    for (int i = 0 ; i < MAXN ; i++) is_prime[i] = true;
    is_prime[0] = false;
    is_prime[1] = false;
    cas = 0;
    for (int i = 2 ; i < MAXN ; i++)
    {
        if (is_prime[i])
        {
            prime[cas++] = i;
            for (int j = i + i ; j < MAXN ; j += i)
                is_prime[j] = false;
        }
    }
}

int main()
{
    init();
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        LL a,b;
        scanf("%lld%lld",&a,&b);
        if (b <= 80000)
        {
            int cnt = 0;
            for (int i = a ; i <= b ; i++)
                if (is_prime[i]) cnt++;
            printf("Case %d: %d\n",kase++,cnt);
            continue;
        }
        else
        {
            if (a <= 2) a = 2;
            int sz = b - a;
            for (int i = 0 ; i <= sz ; i++) flag[i] = true;
            for (int i = 0 ; i < cas && prime[i] * prime[i] <= b ; i++)
            {
                int k = a / prime[i];
                if (k * prime[i] < a) k++;
                if (k <= 1) k++;
                while (k * prime[i] <= b)
                {
                    flag[k * prime[i] - a] = false;
                    k++;
                }
            }
            int cnt = 0;
            for (int i = 0 ; i <= sz ; i++)
                if (flag[i] == true) cnt++;
            printf("Case %d: %d\n",kase++,cnt);
        }
    }
    return 0;
}

LightOj 1138 Trailing Zeroes (III)

最小的数阶乘末尾的0的个数

每个因子2*5可以出个末尾0,那么有从小到大的过程中,2的数量绝对够多,于是变成了从1到N中5的因子的个数

另外为了优化需要套上一个二分代码。

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
LL Q;
const LL INF = 0x3f3f3f3f;

bool judge(LL mid)
{
    int cnt = 0;
    while (mid)
    {
        cnt += mid / 5;
        mid /= 5;
    }
    return cnt >= Q;
}

int main()
{
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%lld",&Q);
        LL L = 0 ,R = INF;
        LL ans = -1;
        while (L <= R)
        {
            LL mid = (L + R) / 2;
            if (judge(mid))
            {
                R = mid - 1;
                ans = mid;
            }
            else L = mid + 1;
        }
        bool flag = true;
        LL tmp = ans;
        LL val = 0;
        while (tmp)
        {
            val += tmp / 5;
            tmp /= 5;
        }
        if (val != Q) flag = false;
        if (flag)   printf("Case %d: %lld\n",kase++,ans);
        else printf("Case %d: impossible\n",kase++);
    }
    return 0;
}

接下来是几个大白的题目

Uva 11426 GCD - Extreme (II)

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
const int MAXN = 4000000;
int phi[MAXN + 10];
LL ret[MAXN + 10];

void init()
{
    memset(ret,0,sizeof(ret));
    for(int i = 1 ; i <= MAXN ; i++) phi[i] = i;
    for(int i = 2 ; i <= MAXN; i ++)
    {
        if(phi[i] == i)
        {
            for(int j = i ; j <= MAXN ; j += i)
                phi[j] = phi[j] / i * (i - 1);
        }
        for(int j = 1; j * i <= MAXN ; j ++)
            ret[j * i] += j * phi[i];
    }
    for (int i = 1 ; i <= MAXN ; i++) ret[i] += ret[i - 1];
}

int main()
{
    init();
    int N;
    while (scanf("%d",&N) != EOF) if (N == 0) break;
        else printf("%lld\n",ret[N]);
    return 0;
}

UVA 11754 Codefeat

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
void gcd(LL a,LL b,LL &d,LL &x,LL &y)
{
        if (b == 0) {d = a; x = 1; y = 0;}
        else  {gcd(b,a % b,d,y,x); y -= x * (a / b);}
}
LL china(int n,int *a,int *m)
{
        LL M = 1,d,y,x = 0;
        for (int i = 0 ; i < n ; i++) M *= m[i];
        for (int i = 0 ; i < n ; i++)
        {
                LL w = M / m[i];
                gcd(m[i],w,d,d,y);
                x = (x + y * w * a[i]) % M;
        }
        return (x + M) % M;
}
const int MAXC = 9;
const int MAXK = 100;
const int LIMIT = 10000;
set<int>value[MAXC];
int C,X[MAXC],K[MAXC];
int Y[MAXC][MAXK];
void slove_enum(int S,int bc)
{
        for (int  c = 0 ; c < C; c++) if (c != bc)
        {
                value[c].clear();
                for (int i = 0 ; i < K[c] ; i++)  value[c].insert(Y[c][i]);
        }
        for (int t = 0 ; S != 0 ; t++)
        {
                for (int i = 0 ; i < K[bc] ; i++)
                {
                        LL n = (LL)X[bc] * t + Y[bc][i];
                        if (n == 0) continue;
                        bool flag = true;
                        for (int c = 0 ; c < C; c++)
                        {
                                if (c != bc)
                                {
                                        if (value[c].count(n % X[c]) == 0) {flag = false; break;}
                                }
                        }
                        if (flag) { printf("%lld\n",n); if (--S == 0) break;}
                }
        }
}
int a[MAXC];
vector<LL>sol;
void dfs(int depth)
{
        if (depth == C) sol.push_back(china(C,a,X));
        else for (int i = 0 ; i < K[depth]; i++)
        {
                a[depth] = Y[depth][i];
                dfs(depth + 1);
        }
}
void slove_china(int S)
{
        sol.clear();
        dfs(0);
        sort(sol.begin(),sol.end());
        LL M = 1;
        for (int i = 0 ; i < C; i++) M *= X[i];
        vector<LL>ans;
        for (int i = 0; S != 0 ; i++)
        {
                for (int j = 0 ; j < (int)sol.size(); j++)
                {
                        LL n = M * i + sol[j];
                        if (n > 0)
                        {
                                printf("%lld\n",n);
                                if (--S == 0) break;
                        }
                }
        }
}
int main()
{
        int S;
        while (scanf("%d%d",&C,&S) != EOF)
        {
                if (C == 0) break;
                LL tot = 1;
                int best = 0;
                for (int c = 0 ; c < C ; c++)
                {
                        scanf("%d%d",&X[c],&K[c]);
                        tot *= K[c];
                        for (int i = 0 ; i < K[c]; i++) scanf("%d",&Y[c][i]);
                        sort(Y[c],Y[c] + K[c]);
                        if (K[c] * X[best] < K[best] * X[c]) best = c;
                }
                if (tot > LIMIT) slove_enum(S,best);
                else slove_china(S);
                printf("\n");
        }
        return 0;
}

UVA 11916 Emoogle Grid

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
LL N,K,B,R;
const LL MOD = 100000007;
const int MAXN = 1010;
int x[MAXN],y[MAXN];
LL M;
set<pair<int,int> >s;

LL pow_mod(LL x,int cnt)
{
    LL ret = 1;
    while (cnt)
    {
        if (cnt & 1) ret = ret * x % MOD;
        x = x * x % MOD;
        cnt >>= 1;
    }
    return ret;
}

void ext_gcd(LL a,LL b,LL &d,LL &x,LL &y)
{
    if (b == 0) {d = a; x = 1 ; y = 0;}
    else {ext_gcd(b,a % b,d,y,x); y -= x * (a / b);}
}

LL inv(LL a,LL n)
{
    LL d,x,y;
    ext_gcd(a,n,d,x,y);
    return d == 1 ? (x + n) % n : -1;
}

LL log_mod(LL a,LL b,LL n)
{
    LL m,v,e = 1;
    m = (LL)sqrt(n + 0.5);
    v = inv(pow_mod(a,m),n);
    map<LL,LL>x;
    x[1] = 0;
    for (int i = 1 ; i < m ; i++)
    {
        e = e * a % m;
        if (!x.count(e)) x[e] = (LL)i;
    }
    for (int i = 0 ; i < m ; i++)
    {
        if (x.count(b)) return (LL)i * m + x[b];
        b = b * v % n;
    }
    return -1;
}

LL getnum()
{
    int tot = 0;
    for (int i = 1 ; i <= B ; i++)
    {
        if (x[i] != M && !s.count(make_pair(x[i] + 1,y[i]))) tot++;
    }
    tot += N;
    for (int i = 1 ; i <= B ; i++) if (x[i] == 1) tot--;
    return (pow_mod(K,tot) * pow_mod(K - 1,(M * N  - tot - B))) % MOD;
}

LL calcu()
{
    LL cnt = getnum();
    printf("%d\n",cnt);
    if (cnt == R) return M;
    int num = 0;
    for (int i = 1 ; i <= B ; i++) if (x[i] == M) num++;
    cnt = (cnt * pow_mod(K,num)) % MOD;
    cnt = (cnt * pow_mod(K - 1,N - num)) % MOD;
    if (cnt == R)return M + 1;
    //printf("%lld %lld\n",pow_mod(K - 1,N),pow_mod(K - 1,N));
    return log_mod(pow_mod(K - 1,N),R * pow_mod(K - 1,N),MOD) + M + 1;
}
int main()
{
    int T,kase = 1;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%lld%lld%lld%lld",&N,&K,&B,&R);
        R %= MOD;
        s.clear();
        M = 1;
        for (int i = 1 ; i <= B ; i++)
        {
            scanf("%d%d",&x[i],&y[i]);
            M = max(M,(LL)x[i]);
            s.insert(make_pair(x[i],y[i]));
        }
        printf("Case %d: %lld\n",kase++,calcu());
    }
    return 0;
}

POJ 2115 同青蛙的约会

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
LL gcd(LL a, LL b) {return a % b == 0 ? b : gcd(b, a % b);}
LL ext_gcd(LL a,LL b,LL &x,LL &y)
{
    if (a == 0 && b == 0) return -1;
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    LL d = ext_gcd(b,a % b,y,x);
    y -= a / b * x;
    return d;
}
LL A,B,C,K;

int main()
{
    while (scanf("%I64d%I64d%I64d%I64d",&A,&B,&C,&K) != EOF)
    {
        if (A == 0 && B == 0 && C == 0 && K == 0) break;
        LL a = C, b = (1LL << K), c = B - A;
        LL d = gcd(a,b);
        if (c % d != 0)
        {
            puts( "FOREVER" );
            continue;
        }
        a /= d;
        b /= d;
        LL x,y;
        ext_gcd(a,b,x,y);
        //cout << a << " " << b << " " << x << " " << y << endl;
        x *= c / d;
        y *= c / d;
        //cout << y << endl;
        //cout << x << endl;
        LL  tmp = (1LL << K) / d;
        x = (x % tmp + tmp) % tmp;
        printf("%I64d\n",x);
    }
    return 0;
}

HDU 2161 Prime太水了。

UVA 11827 太水了

UVA 10200 太水了

SGU 106 The equation

判断欧几里德可行解在固定区间内的个数

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define PI 3.1415926535897932626
using namespace std;
LL gcd(LL a, LL b) {return a % b == 0 ? b : gcd(b, a % b);}
LL a,b,c,x1,x2,yy1,y2;
LL x0,yy0;
LL ext_gcd(LL a,LL b,LL &x,LL &y)
{
    if (a == 0 && b == 0) return -1;
    if (b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    LL d = ext_gcd(b,a % b,y,x);
    y -= a / b * x;
    return d;
}

int main()
{
    while (scanf("%I64d%I64d%I64d%I64d%I64d%I64d%I64d",&a,&b,&c,&x1,&x2,&yy1,&y2) != EOF)
    {
        c = -c;
        if (c < 0)
        {
            a = -a;
            b = -b;
            c = -c;
        }
        if (a < 0)
        {
            a = -a;
            LL tmp = -x1;
            x1 = -x2;
            x2 = tmp;
        }
        if (b < 0)
        {
            b = -b;
            LL tmp = -yy1;
            yy1 = - y2;
            y2 = tmp;
        }
        if (a == 0 && b == 0)
        {
            if (c == 0)
            {
                printf("%I64d\n",(x2 - x1 + 1) * (y2 - yy1 + 1));
            }
            printf("%d\n",0);
            continue;
        }
        else if (a == 0)
        {
            if (c % b == 0)
            {
                if (c / b >= yy1 && c / b <= y2)
                {
                    printf("%I64d\n",x2 - x1 + 1);
                }
                else printf("%d\n",0);
            }
            continue;
        }
        else if (b == 0)
        {
            if (c % a == 0)
            {
                if (c / a >= x1 && c / a <= x2)
                {
                    printf("%I64d\n",y2 - yy1 + 1);
                }
                printf("%d\n",0);
            }
            continue;
        }
        LL d = gcd(a,b);
        if (c % d != 0)
        {
            puts("0");
            continue;
        }
        a = a / d;
        b = b / d;
        c = c / d;
        ext_gcd(a,b,x0,yy0);
        x0 *= c;
        yy0 *= c;
       // printf("%I64d %I64d %I64d %I64d %I64d\n",a,b,c,x0,yy0);
        LL l1 = (LL)ceil((double)(x1 - x0) / (double)(b));
        LL l2 = (LL)ceil((double)(yy0 - y2) / (double)(a));
        LL r1 = (LL)floor((double)(x2 - x0) / (double)(b));
        LL r2 = (LL)floor((double)(yy0 - yy1) / (double)(a));
       // cout << l1 << " " << r1 << endl;
       // cout << l2 << " " << r2 << endl;
        LL l = max(l1,l2);
        LL r = min(r1,r2);
        if (l > r) puts("0");
        else printf("%I64d\n",r - l + 1LL);
    }
    return 0;
}

POJ 2478 直接欧拉前N想和。

UVA 11752 The Super Powers

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <stack>
#include <queue>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL unsigned long long
#define PI 3.1415926535897932626
using namespace std;
int gcd(int a, int b) {return a % b == 0 ? b : gcd(b, a % b);}
set<LL>ans;
set<LL>::iterator it;
bool is_prime[110];

void init()
{
    for (int i = 0 ; i < 110 ; i++) is_prime[i] = true;
    is_prime[0] = is_prime[1] = true;
    for (int i = 2 ; i < 110 ; i++)
    {
        if (is_prime[i])
        {
            for (int j = i + i ; j < 110 ; j += i)
                is_prime[j] =  false;
        }
    }
}

int main()
{
    init();
    ans.clear();
    ans.insert(1);
    for (LL i = 2 ; i < (1 << 16) ; i++)
    {
        LL limit = (LL)ceil(64.0 * log10(2.0) / log10(i));
        //cout << i << " " << limit << endl;
       // scanf("%*d");
        LL cur = 1;
        for (int j = 1 ; j < limit ; j++)
        {
            cur *= i;
            if (is_prime[j] == false)
            {
                ans.insert(cur);
               // cout << cur << endl;
               // scanf("%*d");
            }
        }
    }
    int cnt = 0;
    for (it = ans.begin() ; it != ans.end() ; it++)
     cout << *it << endl;
    return 0;
}

时间: 2024-10-12 22:59:52

kuangbin 带你飞 数学基础的相关文章

Tarjan 联通图 Kuangbin 带你飞 联通图题目及部分联通图题目

Tarjan算法就不说了 想学看这 https://www.byvoid.com/blog/scc-tarjan/ https://www.byvoid.com/blog/biconnect/ 下面是几份基本的模版 首先是无向图割点桥的代码 下面的代码是用于求割点数目的 其中add_block[u] = x  表示删除u点之后增加的联通块个数.注意是增加的联通块个数 const int MAXN = 1010; const int MAXM = 10010; const int INF = 0x

kuangbin带你飞专题一 简单搜索 题解

目录 [kuangbin带你飞]专题一 简单搜索 [kuangbin带你飞]专题一 简单搜索 总结:用时2天半终于把这个专题刷完了 对于最基础的dfs bfs 路径打印 状态转移也有了一点自己些微的理解 其实2天半可以压缩到1天半的 主要是自己太懒了...慢慢加油刷bin神的专题呀 从大二下学期开始学算法 一开始就知道这个专题 一开始对于这个专题里的所有问题感觉都好难啊..就直接放弃了 看lrj的书 现在看到这个专题还挺唏嘘的吧 突然觉得思维和想法也不是很难 果然是那个时候心不静&还是储量不够吗

「kuangbin带你飞」专题十八 后缀数组

layout: post title: 「kuangbin带你飞」专题十八 后缀数组 author: "luowentaoaa" catalog: true tags: - kuangbin - 字符串 - 后缀数组 传送门 倍增法 struct DA{ bool cmp(int *r,int a,int b,int l){ return r[a]==r[b]&&r[a+l]==r[b+l]; } int t1[maxn],t2[maxn],c[maxn]; int r

「kuangbin带你飞」专题十二 基础DP

layout: post title: 「kuangbin带你飞」专题十二 基础DP author: "luowentaoaa" catalog: true tags: mathjax: true - kuangbin - 动态规划 传送门 A.HDU1024 Max Sum Plus Plus 题意 给你N个数,然后你分成M个不重叠部分,并且这M个不重叠部分的和最大. 思路 动态规划最大m字段和,dp数组,dp[i][j]表示以a[j]结尾的,i个字段的最大和 两种情况:1.第a[j

「kuangbin带你飞」专题二十二 区间DP

layout: post title: 「kuangbin带你飞」专题二十二 区间DP author: "luowentaoaa" catalog: true tags: - kuangbin - 区间DP - 动态规划 传送门 B.LightOJ - 1422 Halloween Costumes 题意 按顺序参加舞会,参加一个舞会要穿一种衣服,可以在参加完一个舞会后套上另一个衣服再去参加舞会,也可以在参加一个舞会的时候把外面的衣服脱了,脱到合适的衣服,但是脱掉的衣服不能再穿,参加完

「kuangbin带你飞」专题二十 斜率DP

layout: post title: 「kuangbin带你飞」专题二十 斜率DP author: "luowentaoaa" catalog: true tags: mathjax: true - kuangbin - 动态规划 - 斜率DP 传送门 A.HDU - 3507 Print Article 题意 就是输出序列a[n],每连续输出的费用是连续输出的数字和的平方加上常数M 让我们求这个费用的最小值. 题解 概率DP的入门题,把我搞得要死要活的. 首先dp[i]表示输出前i

[kuangbin带你飞]专题十六 KMP &amp; 扩展KMP &amp; Manacher :G - Power Strings POJ - 2406(kmp简单循环节)

[kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher G - Power Strings POJ - 2406 题目: Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of

跟着chengyulala刷题之[kuangbin带你飞]之&#39;并查集&#39;专题/斜眼笑

[kuangbin带你飞] 专题1-23 https://vjudge.net/article/187 专题五 并查集 POJ 2236 Wireless Network  http://poj.org/problem?id=2236POJ 1611 The Suspects  http://poj.org/problem?id=1611HDU 1213 How Many Tables  http://acm.hdu.edu.cn/showproblem.php?pid=1213HDU 3038

[kuangbin]带你飞之&#39;线段树&#39;专题(未完成)

// 带飞网址 https://vjudge.net/article/187 专题七 线段树 HDU 1166 敌兵布阵HDU 1754 I Hate It√ POJ 3468 A Simple Problem with IntegersPOJ 2528 Mayor's postersHDU 1698 Just a HookZOJ 1610 Count the ColorsPOJ 3264 Balanced LineupHDU 4027 Can you answer these queries?