无数人fst了B,我也身在其中,先开C的都太机智了
在[l,r]上取三个数a,b,c(a < b < c) 使 b不能被a整除,c不能被b整除,但c能被a整除。因为r-l<=50 , 暴力
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define LL long long LL gcd(LL a, LL b) { if (!b) return a; else return gcd(b, a%b); } int main() { LL ll, rr; LL l, r; l = ll, r = rr; scanf("%lld%lld", &l, &r); for (LL i = l+1; i < r; i++) { for (LL ll = l; ll < i; ll++) { for (LL rr = i+1; rr <= r; rr++) { if (gcd(ll, rr) != 1 && gcd(ll, i) == 1 && gcd(i, rr) == 1) { printf("%lld %lld %lld\n", ll, i, rr); return 0; } } } } printf("-1\n"); return 0; }
从1-v中选出cn1个元素不能被x整除,cn2个元素不能被y整除,且这cn1+cn2个元素不同,求最小的v
一个数n,若n/m==k,说明1,2,3----n有k个数能被m整除,则剩n-k个数不能被m整除,本题根据这个性质对n在1到(long long)1e18 二分
#include <cstdio> #include <algorithm> using namespace std; typedef long long LL; LL c1, c2 ,x, y; bool ok(LL n) { LL a = n - n/x; LL b = n - n/y; LL c = n - n/x/y; return a >= c1 && b >= c2 && c >= c1 + c2; } int main() { //freopen("in.txt", "r", stdin); scanf("%lld%lld%lld%lld", &c1, &c2, &x, &y); LL l = 1, r = (LL)1e13; while (l <= r) { // LL m = (r - l) >> 1 + l; LL m = (l+r) >> 1; if (ok(m)) r = m - 1; else l = m + 1; } printf("%lld\n", l); return 0; }
给出1-n的一个序列A,对于1<=i <= n-1不同的|Ai-Ai-1|的个数为k
可以构造这么一个序列: 1 n 2 n-1 3 n-2....产生了最多 n - 1个不同的数对 ,比如对于 n = 6, 序列为 : 1 6 2 5 3 4
1 2 3 4 5 6 进行一次 操作
1 6 2 3 4 5 得到 3 个 不同的值 (5,4,1),再进行一次操作
1 6 2 5 3 4 得到 5 个不同的值 (5,4,3,2,1)
一般的, 每进行m次操作,我们能得到2*m+1个不同的值,如果想得到2*m个值,在2*m+1的基础上交换第1个和第2个元素就好了
但有一点要注意的(比赛最后一个小时被绕蒙了),比如n=5,两次操作最多有4个不同的值,如果k = 3这时候不需要交换第1,2个元素
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define LL long long const int N = (int) 1e5+1; int A[N]; int main() { int n, k; scanf("%d%d", &n, &k); int kk = k; bool ok = false; if (k%2 == 1) { k = (k - 1) / 2; } else { k = (k - 1) / 2 + 1; if (kk != n-1) ok = true; } int cnt = 0; for (int i = 1; i <= n; i++) { if (i%2 == 1) A[i] = i - cnt; if (i%2 == 0) { if (k > 0) { A[i] = n + 1 - A[i-1]; k--; cnt++; } else A[i] = i - cnt; } } if (ok) { int tem = A[1]; A[1] = A[2]; A[2] = tem; } printf("%d", A[1]); for (int i = 2; i <= n; i++) printf(" %d", A[i]); printf("\n"); return 0; }
给出n个元素的一个序列A,给出m个限制,每个限制由三个数字组成,l,r,q要求A[l]&A[l+1]&...&A[r] = q如果存在这样的序列,输出A[1],A[2]......A[n]
#include <cstdio> #include <cstring> #define Maxbit 29 #define M 110000 const int INF = (1<<30)-1; int n, k; int sum[M], tree[M*4]; int l[M], r[M], q[M], a[M]; void build (int l, int r, int rt) { if (l == r) { tree[rt] = a[l]; return; } int m = (l+r)>>1; build(l, m, rt<<1); build(m+1, r, rt<<1|1); tree[rt] = tree[rt<<1]&tree[rt<<1|1]; } int query (int L, int R, int l, int r, int rt) { if (r < L || l > R) return INF; if (L <= l && R >= r) return tree[rt]; int m = (l+r)>>1; return query(L, R, l, m, rt<<1) & query(L, R, m+1, r, rt<<1|1); } void init() { scanf("%d%d", &n, &k); for (int i = 1; i <= k; i++) scanf("%d%d%d", &l[i], &r[i], &q[i]); for (int i = 0; i <= Maxbit; i++) { memset(sum, 0, sizeof(sum)); for (int j = 1; j <= k; j++) if ((q[j]>>i)&1) { sum[l[j]]++; sum[r[j]+1]--; } for (int j = 1; j <= n; j++) { sum[j] += sum[j-1]; if (sum[j] > 0) a[j] |= 1 << i; } } build(1, n, 1); } void solve() { for (int i = 1; i <= k; i++) if (query(l[i], r[i], 1, n, 1) != q[i]) { printf("NO\n"); return; } printf("YES\n"); for (int i = 1; i <= n; i++) printf("%d ", a[i]); printf("\n"); } int main() { init(); solve(); return 0; }
给出n个长度相同,由大小写字母组成的字符串。朋友随机选择其中一个字串,每次你可以问朋友他选的串的某一个位置上的字符是什么,求猜对该字符串的期望
// by tourist 研究ing #include <cstring> #include <vector> #include <list> #include <map> #include <set> #include <deque> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include <memory.h> #include <cassert> using namespace std; const int BITS = 17; const int MAX = (1 << BITS) - 1; int kb[1 << BITS]; const int N = (1 << 21) + 10; long long bad[N]; double f[N]; char word[777][777]; int main() { int cnt; scanf("%d", &cnt); for (int i = 0; i < cnt; i++) { scanf("%s", word[i]); } int n = strlen(word[0]); for (int t = 0; t < (1 << n); t++) { bad[t] = 0; } for (int i = 0; i < cnt; i++) { for (int j = i + 1; j < cnt; j++) { int diff = 0; for (int k = 0; k < n; k++) { if (word[i][k] == word[j][k]) { diff |= (1 << k); } } bad[diff] |= (1LL << i); bad[diff] |= (1LL << j); } } kb[0] = 0; for (int i = 1; i < (1 << BITS); i++) { kb[i] = kb[i & (i - 1)] + 1; } for (int t = (1 << n) - 1; t >= 0; t--) { for (int i = 0; i < n; i++) { if (t & (1 << i)) { bad[t ^ (1 << i)] |= bad[t]; } } int p = 0; f[t] = 0.0; for (int i = 0; i < n; i++) { if (!(t & (1 << i))) { f[t] += f[t ^ (1 << i)]; p++; } } if (p > 0) { f[t] /= p; } f[t] += (kb[bad[t] & MAX] + kb[(bad[t] >> BITS) & MAX] + kb[(bad[t] >> (2 * BITS))]) * 1.0 / cnt; } printf("%.17lf\n", f[0]); return 0; }