[POI2015]LAS-Łasuchy 题解
题目地址:洛谷:【P3584】[POI2015]LAS – 洛谷、BZOJ:P …
May all the beauty be blessed.
题目地址:洛谷:【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;
}
题目地址: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.
给你一个序列,两种操作:
输入格式:
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;
}
题目地址:洛谷:【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;
}