很抱歉过了这么多天才补这场,最近真的挺忙的……
出题人是朝鲜的(目测是金策工业?),挺难。
题目链接:http://acm.hdu.edu.cn/contests/contest_show.php?cid=851
A:
签到题。
对于当前的点,若其编号为偶数,则可与1相连使得边权贡献为0。否则从低位向高位找当前点编号的二进制表示的第一个0,使这个0变为1,其他位置变为0并检查新的数字是否小于等于n。若小于等于n则贡献为0,反之贡献为1。
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson (curpos<<1) 15 #define rson (curpos<<1|1) 16 /* namespace */ 17 using namespace std; 18 /* header end */ 19 20 const int maxn = 2e7; 21 ll bin[60]; 22 int ans[maxn]; 23 24 int main() { 25 bin[0] = 1; 26 for (int i = 1; i <= 40; i++) bin[i] = (bin[i - 1] << 1); 27 int T; cin >> T; 28 while (T--) { 29 int n; 30 cin >> n; 31 int sum = 0; 32 for (int i = 1; i <= n; i++) { 33 if (!(i & 1)) { 34 ans[i] = 1; 35 continue; 36 } 37 for (int j = 0; j <= 31; j++) { 38 if ((i & bin[j]) == 0) { 39 if (bin[j] <= n) ans[i] = bin[j]; 40 else { 41 ans[i] = 1; 42 sum++; 43 } 44 break; 45 } 46 } 47 } 48 cout << sum << endl; 49 for (int i = 2; i <= n - 1; i++) cout << ans[i] << " "; 50 cout << ans[n] << endl; 51 } 52 return 0; 53 }
B:
C:
D:
E:
F:
G:
一开始还以为是反向bfs,白给了两发。
题目说明120步之后就能作判断。可以先比较初始矩阵和目标矩阵数字1、2、3、4的位置,再比较5、6、7、8,以此类推。因为前面的数排完之后就没有后效性了。可以从1*n的矩阵思考,再数学归纳到n*n来思考这个问题。
事实上这是个关于奇数码游戏(就是题目给的游戏)的结论题:奇数码游戏两个局面可达,当且仅当两个局面下网格中的数依次写成一行含有n^2-1个元素的序列中,逆序对个数的奇偶性相同。该结论必要性显然:当空格左右移动时,写成的序列显然不变,不改变逆序对个数奇偶性;空格上下移动时,相当于某个数与它前(或后)边的n-1个数交换了位置,因为n-1是购书,所以逆序对数的变化也只能是偶数。
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson (curpos<<1) 15 #define rson (curpos<<1|1) 16 /* namespace */ 17 using namespace std; 18 /* header end */ 19 20 const int maxn = 20; 21 22 int main() { 23 int t; scanf("%d", &t); 24 while (t--) { 25 int ans = 0, a[maxn]; 26 rep0(i, 0, 16) { 27 scanf("%d", &a[i]); 28 if (!a[i]) ans += i / 4 + 1 + i % 4 + 1, a[i] = 16; 29 rep1(j, 0, i) if (a[j] > a[i]) ans++; 30 } 31 if (ans & 1) puts("No"); 32 else puts("Yes"); 33 } 34 return 0; 35 }
H:
给定一维坐标系上的n个整点和m次询问,每次询问给定L,R,p,K。问在区间[L,R]内到点p距离第K小,输出其距离。
二分答案,看区间[p-ans,p+ans]内有没有k个数。
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson (curpos<<1) 15 #define rson (curpos<<1|1) 16 /* namespace */ 17 using namespace std; 18 /* header end */ 19 20 const int maxn = 1e6 + 10; 21 int a[maxn], root[maxn], cnt = 0; 22 23 struct Node { 24 int l, r, sum; 25 } segt[maxn * 40]; 26 27 void update(int pos, int curl, int curr, int &curroot, int &lastroot) { 28 segt[++cnt] = segt[lastroot], segt[cnt].sum++, curroot = cnt; 29 if (curl == curr) return; 30 int mid = curl + curr >> 1; 31 if (pos <= mid) update(pos, curl, mid, segt[curroot].l, segt[lastroot].l); 32 else update(pos, mid + 1, curr, segt[curroot].r, segt[lastroot].r); 33 } 34 35 int query(int lRoot, int rRoot, int curl, int curr, int ql, int qr) { 36 if (ql <= curl && curr <= qr) 37 return segt[rRoot].sum - segt[lRoot].sum; 38 if (curl == curr) return 0; 39 int mid = curl + curr >> 1; 40 if (qr <= mid) return query(segt[lRoot].l, segt[rRoot].l, curl, mid, ql, qr); 41 else if (ql > mid) return query(segt[lRoot].r, segt[rRoot].r, mid + 1, curr, ql, qr); 42 else return query(segt[lRoot].l, segt[rRoot].l, curl, mid, ql, mid) + query(segt[lRoot].r, segt[rRoot].r, mid + 1, curr, mid + 1, qr); 43 } 44 45 int main() { 46 int t; scanf("%d", &t); 47 while (t--) { 48 cnt = 0; 49 int n, q, maxx; scanf("%d%d", &n, &q); 50 for (int i = 1; i <= n; i++) { 51 scanf("%d", &a[i]); 52 maxx = max(maxx, a[i]); 53 } 54 for (int i = 1; i <= n; i++) 55 update(a[i], 1, maxx, root[i], root[i - 1]); 56 int lastAns = 0; 57 while (q--) { 58 int l, r, p, k; scanf("%d%d%d%d", &l, &r, &p, &k); 59 l ^= lastAns, r ^= lastAns, p ^= lastAns, k ^= lastAns; 60 int upBound = maxx, lowBound = 0, ans = maxx; 61 while (lowBound <= upBound) { 62 int mid = lowBound + upBound >> 1; 63 if (query(root[l - 1], root[r], 1, maxx, p - mid, p + mid) >= k) { 64 ans = mid; 65 upBound = mid - 1; 66 } else lowBound = mid + 1; 67 } 68 lastAns = ans; 69 printf("%d\n", ans); 70 } 71 } 72 return 0; 73 }
J:
给定正整数n(n>=2),把n唯一分解之后输出最小的幂次。
把n用4000以内的质数分解,然后判断剩下的是否为p2,p3,p4,p2q2的形式即可,若都不是,答案为1。
1 /* basic header */ 2 #include <bits/stdc++.h> 3 /* define */ 4 #define ll long long 5 #define dou double 6 #define pb emplace_back 7 #define mp make_pair 8 #define sot(a,b) sort(a+1,a+1+b) 9 #define rep1(i,a,b) for(int i=a;i<=b;++i) 10 #define rep0(i,a,b) for(int i=a;i<b;++i) 11 #define eps 1e-8 12 #define int_inf 0x3f3f3f3f 13 #define ll_inf 0x7f7f7f7f7f7f7f7f 14 #define lson (curpos<<1) 15 #define rson (curpos<<1|1) 16 /* namespace */ 17 using namespace std; 18 /* header end */ 19 20 const int maxn = 4010; 21 int t, tot, p[maxn], vis[maxn]; 22 ll n; 23 24 void getPrime() { 25 for (int i = 2; i < maxn; i++) { 26 if (!vis[i]) p[tot++] = i; 27 for (int j = 0; j < tot && i * p[j] < maxn; j++) { 28 vis[i * p[j]] = 1; 29 if (i % p[j] == 0) break; 30 } 31 } 32 } 33 34 int main() { 35 getPrime(); 36 int t; scanf("%d", &t); 37 while (t--) { 38 scanf("%lld", &n); 39 int cnt = int_inf, flag = 0; 40 for (int i = 0; i < tot; i++) 41 if (n % p[i] == 0) { 42 int num = 0; 43 while (n % p[i] == 0) { 44 num++; n /= p[i]; 45 } 46 if (num == 1) flag = 1; 47 cnt = min(cnt, num); 48 } 49 if (flag) { 50 puts("1"); 51 continue; 52 } 53 if (n == 1) { 54 printf("%d\n", cnt); 55 continue; 56 } 57 ll tmp = pow(n, 0.25); 58 if (tmp * tmp * tmp * tmp == n) cnt = min(cnt, 4); 59 else { 60 ++tmp; 61 if (tmp * tmp * tmp * tmp == n) cnt = min(cnt, 4); 62 else { 63 tmp = pow(n, 0.5); 64 if (tmp * tmp == n) cnt = min(cnt, 2); 65 else { 66 tmp++; 67 if (tmp * tmp == n) cnt = min(cnt, 2); 68 else { 69 tmp = pow(n, 1.0 / 3); 70 if (tmp * tmp * tmp == n) cnt = min(3, cnt); 71 else { 72 tmp++; 73 if (tmp * tmp * tmp == n) cnt = min(3, cnt); 74 else cnt = min(1, cnt); 75 } 76 } 77 } 78 } 79 } 80 printf("%d\n", cnt); 81 } 82 return 0; 83 }
原文地址:https://www.cnblogs.com/JHSeng/p/11279703.html