题目链接:https://arc102.contest.atcoder.jp/assignments
C:
大意:给一个n一个k([1,2e5]),三元组a,b,c,a + b, b + c, a + c都是k的倍数,求出这样的三元组的个数
一个小思维题,还是比较好想的,对k分奇偶讨论一下
k为奇数,显然只有三个数都是k的倍数才行
k为偶数,1,三个数都是k的倍数
2,三个数都是相邻k的倍数的中位数,比如k = 4,n = 11那么选2,6,10也满足条件
开始没开ll,没想到开ll的点在哪
低级错误
#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define pb push_back
#define lowbit(x) x&(-x)
#define PII pair<int, int>
#define all(x) x.begin(), x.end()
#define FAST ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int mod = (int)1e9 + 7;
const int maxn = (int)1e5 + 5;
using namespace std;
#define int ll
int32_t main()
{
int n, k; cin >> n >> k;
int t = n / k;
ll ans = 0;
if(k & 1){
ans = t * t * t;
}
else{
int t2 = t;
if(n % k >= k / 2) t2++;
ans = t * t * t + t2 * t2 * t2;
}
cout << ans << endl;
return 0;
}
D:
题目大意:
给一个L,让你构造出一个有向图,满足以下条件。
1.n个点m条边,n<=20, m <= 60,每条边有一个权重([0, 1e6]),可以有平行边
2,边的指向永远是编号小的指向编号大的
3,从节点1到节点n恰好有L条路,并且这L条路的长度正好是[0, L-1]
总感觉这个数据范围在疯狂暗示,不过还是想不到解法。
在网上看了一个:
首先,不妨就令有20个点。
对于i[2, 19],与i+1之间建两条边,权值分别为0,2^(20-i-1),这样我们就能得到所有的位。
描述的不是很清楚。。说说这样构造的目的。比如说给个L正好为2的幂,那么加一条边就能很方便的构造出图了。
那么现在考虑给的数不是2的幂,直接说结论吧,我实在是无法理解这个思路的过程。
从低位到高位考虑:先求出这个1是第几位的(p)。在1, 20 - p两个点之间建一条权值为l ^ lowbit(x)的边。还有就是p=19的时候特判一下。
能想到这个思路的正确性。很巧妙。
Ac Code:
#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
#define pb push_back
#define lowbit(x) x&(-x)
#define PII pair<int, int>
#define all(x) x.begin(), x.end()
#define FAST ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int mod = (int)1e9 + 7;
const int maxn = (int)1e5 + 5;
using namespace std;
struct node{
int u, v, w;
node(int tu, int tv, int tw){
u = tu, v = tv, w = tw;
}
};
vector<node> ans;
int32_t main()
{
int l; scanf("%d", &l);
for(int i = 2; i <= 19; i++){
ans.pb(node(i, i + 1, 0));
ans.pb(node(i, i + 1, (1 << (20 - i - 1))));
}
while(l){
int p = log2(lowbit(l));
if(p == 19){
ans.pb(node(1, 2, 0));
ans.pb(node(1, 2, 1 << 18));
}
else ans.pb(node(1, 20 - p, l ^ lowbit(l)));
l ^= lowbit(l);
}
printf("%d %d\n", 20, ans.size());
for(auto i : ans){
printf("%d %d %d\n", i.u, i.v, i.w);
}
return 0;
}
脑阔疼,学了数位dp一定回来看看这题