作者: KSkun

[POI2015]LAS-Łasuchy 题解

[POI2015]LAS-Łasuchy 题解

题目地址:洛谷:【P3584】[POI2015]LAS – 洛谷、BZOJ:P 

[USACO13OPEN]阴和阳Yin and Yang 题解

[USACO13OPEN]阴和阳Yin and Yang 题解

题目地址:洛谷:【P3085】[USACO13OPEN]阴和阳Yin and Yang & 

[BJWC2012]算不出的等式 题解

[BJWC2012]算不出的等式 题解

题目地址:洛谷:【P4132】[BJOI2012]算不出的等式 – 洛谷、BZOJ:Problem 2659. — [Beijing wc2012]算不出的算式

题目描述

如果你真的很想玩这个游戏,那么就先看看我的题目吧,搞不定这些的话是没办法通关的哟。第一关其实很简单,只有一个关闭的有密码锁的大门。这大门上写着一个奇怪的算式,估计是要你利用它算出密码来开门吧(果然是老掉牙的情节)。
传说中这个式子中的p和q是两个奇质数,等号右边算出来应该就是密码了吧,你是真的算不出来么?
\sum_{k=1}^{\frac{p-1}{2}} \left\lfloor \frac{kq}{p} \right\rfloor + \sum_{l=1}^{\frac{q-1}{2}} \left\lfloor \frac{lp}{q} \right\rfloor =

输入输出格式

输入格式:
只有一行,两个奇质数,分别表示p,q。

输出格式:
一个数,表示算式结果。

输入输出样例

输入样例#1:

5 7

输出样例#1:

6

说明

p,q在32位整型范围内。

题解

我们来观察一个\sum_{k=1}^{\frac{p-1}{2}} \left\lfloor \frac{kq}{p} \right\rfloor有什么意义。我们可以把它转化为在横坐标范围只有 \left\lfloor \frac{p}{2} \right\rfloor ,纵坐标范围只有 \left\lfloor \frac{q}{2} \right\rfloor 的坐标系中,在直线y = \frac{q}{p} x下方的坐标中不含0的整点数目。
分别考察本题加号两边的两项,可以发现第二项只是把第一项对应的坐标系旋转倒置了一下,其答案应该等于第一项,即该坐标系中的所有整点数。这个答案是\left\lfloor \frac{p}{2} \right\rfloor \left\lfloor \frac{q}{2} \right\rfloor
但是当p与q相等的时候,直线y=x上的整点被计算了两遍,即此时的答案应该是 \left\lfloor \frac{p}{2} \right\rfloor (\left\lfloor \frac{p}{2} \right\rfloor + 1)

代码

// Code by KSkun, 2018/6
#include <cstdio>
#include <cctype>

#include <algorithm>

typedef long long LL;

inline char fgc() {
    static char buf[100000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
        ? EOF : *p1++;
}

inline LL readint() {
    register LL res = 0, neg = 1; register char c = fgc();
    for(; !isdigit(c); c = fgc()) if(c == '-') neg = -1;
    for(; isdigit(c); c = fgc()) res = (res << 1) + (res << 3) + c - '0';
    return res * neg;
}

LL p, q;

int main() {
    p = readint(); q = readint();
    printf("%lld", (p / 2) * (q / 2) + (p == q ? p / 2 : 0));
    return 0;
}
[CQOI2012]交换棋子 题解

[CQOI2012]交换棋子 题解

题目地址:洛谷:【P3159】[CQOI2012]交换棋子 – 洛谷、BZOJ 

[SCOI2009]windy数 题解

[SCOI2009]windy数 题解

题目地址:洛谷:【P2657】[SCOI2009]windy数 – 洛谷、BZ 

[SPOJ-GSS4]Can you answer these queries IV 题解

[SPOJ-GSS4]Can you answer these queries IV 题解

题目地址:SPOJ:SPOJ.com – Problem GSS4、洛谷:【SP2713】GSS4 – Can you answer these queries IV – 洛谷

题目描述

You are given a sequence A of N(N <= 100,000) positive integers. There sum will be less than 10^18 . On this sequence you have to apply M (M <= 100,000) operations:
(A) For given x,y, for each elements between the x-th and the y-th ones (inclusively, counting from 1), modify it to its positive square root (rounded down to the nearest integer).
(B) For given x,y, query the sum of all the elements between the x-th and the y-th ones (inclusively, counting from 1) in the sequence.

题意简述

给你一个序列,两种操作:

  1. 区间每个数开方
  2. 区间求和

输入输出格式

输入格式:
Multiple test cases, please proceed them one by one. Input terminates by EOF.
For each test case:
The first line contains an integer N. The following line contains N integers, representing the sequence A1 .. AN.
The third line contains an integer M. The next M lines contain the operations in the form “i x y”.i=0 denotes the modify operation, i=1 denotes the query operation.

输出格式:
For each test case:
Output the case number (counting from 1) in the first line of output. Then for each query, print an integer as the problem required.
Print an blank line after each test case.
See the sample output for more details.

输入输出样例

输入样例#1:

5
1 2 3 4 5
5
1 2 4
0 2 4
1 2 4
0 4 5
1 1 5
4
10 10 10 10
3
1 1 4
0 2 3
1 1 4

输出样例#1:

Case #1:
9
4
6

Case #2:
40
26

题解

[BZOJ3038]上帝造题的七分钟2是一个题。

代码

// Code by KSkun, 2018/6
#include <cstdio>
#include <cctype>
#include <cmath>

#include <algorithm>

typedef long long LL;

const int MAXN = 100005;

int n, m;

LL a[MAXN], sum[MAXN << 2], mx[MAXN << 2];

#define lch o << 1
#define rch o << 1 | 1
#define mid ((l + r) >> 1)

inline void build(int o, int l, int r) {
    if(l == r) {
        mx[o] = sum[o] = a[l]; return;
    }
    build(lch, l, mid);
    build(rch, mid + 1, r);
    sum[o] = sum[lch] + sum[rch];
    mx[o] = std::max(mx[lch], mx[rch]);
}

inline void modify(int o, int l, int r, int ll, int rr) {
    if(l == r) {
        mx[o] = sum[o] = sqrt(sum[o]); return;
    }
    if(ll <= mid && mx[lch] > 1) modify(lch, l, mid, ll, rr);
    if(rr > mid && mx[rch] > 1) modify(rch, mid + 1, r, ll, rr);
    sum[o] = sum[lch] + sum[rch];
    mx[o] = std::max(mx[lch], mx[rch]);
}

inline LL query(int o, int l, int r, int ll, int rr) {
    if(l >= ll && r <= rr) return sum[o];
    LL res = 0;
    if(ll <= mid) res += query(lch, l, mid, ll, rr);
    if(rr > mid) res += query(rch, mid + 1, r, ll, rr);
    return res;
}

int op, l, r;

int main() {
    int kase = 0;
    while(scanf("%d", &n) != EOF) {
        printf("Case #%d:\n", ++kase);
        for(int i = 1; i <= n; i++) {
            scanf("%lld", &a[i]);
        }
        build(1, 1, n);
        scanf("%d", &m);
        while(m--) {
            scanf("%d%d%d", &op, &l, &r);
            if(l > r) std::swap(l, r);
            if(op == 0) {
                modify(1, 1, n, l, r);
            } else {
                printf("%lld\n", query(1, 1, n, l, r));
            }
        }
        puts("");
    }
    return 0;
}
[BZOJ3211]花神游历各国 题解

[BZOJ3211]花神游历各国 题解

题目地址:洛谷:【P4145】上帝造题的七分钟2 / 花神游历各国 – 洛谷、 

[BZOJ3038]上帝造题的七分钟2 题解

[BZOJ3038]上帝造题的七分钟2 题解

题目地址:洛谷:【P4145】上帝造题的七分钟2 / 花神游历各国 – 洛谷、 

[BZOJ3209]花神的数论题 题解

[BZOJ3209]花神的数论题 题解

题目地址:洛谷:【P4317】花神的数论题 – 洛谷、BZOJ:Problem 3209. — 花神的数论题

题目描述

话说花神这天又来讲课了。课后照例有超级难的神题啦…… 我等蒟蒻又遭殃了。
花神的题目是这样的
设 sum(i) 表示 i 的二进制表示中 1 的个数。给出一个正整数 N ,花神要问你Π(sum(i)),也就是 sum(1)—sum(N) 的乘积。

输入输出格式

输入格式:
一个正整数 N。

输出格式:
一个数,答案模 10000007 的值。

输入输出样例

输入样例#1:

3

输出样例#1:

2

说明

对于样例一,1*1*2=2;
数据范围与约定
对于 100% 的数据,N≤10^15

题解

枚举二进制中含有多少个1,我们可以用数位DP处理出这种情况的方案数,然后快速幂算出结果,乘进答案中。

代码

// Code by KSkun, 2018/6
#include <cstdio>
#include <cctype>
#include <cstring>

#include <algorithm>

typedef long long LL;

inline char fgc() {
    static char buf[100000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
        ? EOF : *p1++;
}

inline LL readint() {
    register LL res = 0, neg = 1; register char c = fgc();
    for(; !isdigit(c); c = fgc()) if(c == '-') neg = -1;
    for(; isdigit(c); c = fgc()) res = (res << 1) + (res << 3) + c - '0';
    return res * neg;
}

const int MAXN = 60, MO = 10000007;

inline LL fpow(LL n, LL k) {
    LL res = 1;
    while(k) {
        if(k & 1) res = (res * n) % MO;
        n = n * n % MO;
        k >>= 1;
    }
    return res;
}

LL n, dp[MAXN][MAXN][MAXN][2], res[MAXN];
int m, num[MAXN];

inline LL dfs(int step, int cnt, int tot, bool lim) {
    if(!step) return cnt == tot;
    if(dp[step][cnt][tot][lim] != -1) return dp[step][cnt][tot][lim];
    LL res = 0; int limm = lim ? num[step] : 1;
    for(int i = 0; i <= limm; i++) {
        res += dfs(step - 1, cnt + (i == 1), tot, lim && i == limm);
    }
    return dp[step][cnt][tot][lim] = res;
}

int main() {
    memset(dp, -1, sizeof(dp));
    n = readint();
    while(n) {
        num[++m] = n & 1; n >>= 1;
    }
    for(int i = 1; i <= m; i++) {
        res[i] = dfs(m, 0, i, true);
    }
    LL ans = 1;
    for(int i = 1; i <= m; i++) {
        ans = ans * fpow(i, res[i]) % MO;
    }
    printf("%lld", ans);
    return 0;
}
[BZOJ2565]最长双回文串 题解

[BZOJ2565]最长双回文串 题解

题目地址:洛谷:【P4555】最长双回文串 – 洛谷、BZOJ:Problem