多校7:
H. xay loves count
题目:给了数组a, 求三元组(i, j, k)的数量,使得 a
i
_i
i * a
j
_j
j = a
k
_k
k
思路:对于a * b = c来说,如果我们知道了c, 那么就可以从 1到
c
\sqrt{c}
c找a, 然后通过a去判断b。
这里可以用一个map把数量存下来,然后遍历
c
\sqrt{c}
c 就好。
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
int b[N];
int n;
map<int, int> mp;
int main(){
cin >> n;
for(int i = 1; i <= n; i++)
{
cin >> b[i];
mp[b[i]]++;
}
ll ans = 0;
for(auto x : mp)
{
int u = x.first, y = x.second;
for(int i = 1; i <= sqrt(u); i++)
{
if(u%i == 0 && mp[u/i] && mp[i]){
if(i == u/i){ //相等的时候i, j不能交换位置
ans += y*mp[i]*mp[u/i];
}else{
ans += 2*y*mp[i]*mp[u/i];
}
}
}
}
cout << ans << endl;
}
I. xay loves or
题目:给你x和s,你需要计算有多少正整数y满足 x
or
\operatorname{or}
or y=s。
思路:我们看二进制中的规律,对于s中的1,如果在x上没有,那么在y上一定有,如果在x上有,那么在y上不一定有。因此y的变化只有x上的1. 所有统计x的1就好。
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
void solve(){
ll x, s;
cin >> x >> s;
if((( x | s) > s) || (x > s)) {
cout << 0 << endl;
return ;
}
ll cot1 = 0, cot2 = 0;
ll n = x;
while(n){
if(n & 1) cot1++;
n >>= 1;
}
ll ans = 1;
for(int i = 1; i <= cot1; i++) ans *= 2;
if(x == s) {
cout << ans-1 << endl;
}else{
cout << ans << endl;
}
}
int main(){
solve();
}
多校8:
A. Ares, Toilet Ares
题目:太长了… 总之就是求一个能过题目的期望(照着题目下面写)。
思路:一开始没看懂,然后怀着忐忑的心情用了除法取模,然后答案就出来了…。
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define int long long
const int mod = 4933;
const int N = 1e5 + 10;
int ksm(int a, int n)
{
int ans = 1;
a %= mod;
while(n){
if(n & 1) ans = ans*a % mod;
a = a*a % mod;
n >>= 1;
}
return ans;
}
signed main(){
int n, m, k, a, l;
cin >> n >> m >> k >> a >> l;
ll ans = 1;
if(k == 0) ans = 0;
for(int i = 1 ; i <= k; i++)
{
int x, y, z;
cin >> x >> y >> z;
if(x == 0) continue;
ans = ans*(z-y)%mod*ksm(z, mod-2)%mod;
}
cout << ((ans+a)%mod) << endl;
}
D. OR
题目:就是说给你长度n - 1的b数组和c数组。一个代表a
i
−
1
_{i-1}
i−1
or
\operatorname{or}
or a
i
_{i}
i, 一个代表a
i
−
1
_{i-1}
i−1
+
\operatorname{+}
+ a
i
_i
i。然后问有多少个数组a满足要求。
思路:我们首先看一个知识点:a + b = a
∣
\operatorname{|}
∣b + a
&
\&
&b。 所以我们可以得到与和或的两个数组。然后很容易观察到只要确定了a
1
_1
1,那么后面的数就确定了。暴力的方法是枚举,但是a最多有230个,所以会T。这里用更简单的思路,我们对每一位二进制分别做一次就好。
就是说我们这里不看整体,只看二进制第一位符不符合,第二位符不符合。
我们分别列举为0和为1的情况,然后简单的逻辑推导。如果b是1且d是1,那么两个一定是1,如果都是0,那么两个都是0。如果一个1一个0,只有b = 1, d = 0时可以,且上一个是1则下一个是0,上一个是0则下一个是1。 – 按照这样的思路写一遍。
代码上比较简洁,而且很是离谱,总之我是想不出来,都是根据大佬们的思路做了一遍后才会做。
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define _ 0
const int maxn = 1e5 + 10;
int b[maxn], c[maxn], d[maxn];
int n;
ll ans = 0;
int main(){
cin >> n;
for(int i = 2; i <= n; i++) cin >> b[i];
for(int i = 2; i <= n; i++) cin >> c[i];
for(int i = 2; i <= n; i++){
d[i] = c[i] - b[i];
}
ll ans = 1;
for(int i = 0; i <= 31; i++)
{
int bt0 = 1, bt1 = 1; //存储0和1的可能性
for(int j = 2; j <= n; j++){
int x = (b[j]>>i)&1, y = (d[j]>>i)&1;
int btt0 = 0, btt1 = 0;
if(x == 0 && y == 0) btt0 = bt0;
if(x == 1 && y == 1) btt1 = bt1;
if(x == 1 && y == 0) btt1 = bt0, btt0 = bt1;
bt1 = btt1, bt0 = btt0;
}
ans *= (bt0 + bt1);
}
cout << ans << endl;
return ~~(0 ^_^ 0);
}
E. Rise of Shadows
题目:找一个质数闰年。
思路:好家伙,竟然有闰年的质数…
#include<iostream>
int main(){
int t;
std::cin >> t;
while(t--){
int n;
std::cin >> n;
std::cout << "no\n";
}
}
K. Yet Another Problem About Pi
题目:给出网格宽和高,然后求能走
π
\pi
π 的长度下能走的最多的网格。
思路:由于没有限定条件,我们就可以把边界线看成无限细但真实存在。而我们的线在线上走可以同时经过边界的两个面 (话说也没有规定我的线有多粗,万一我的车比行星大呢 🙄)。所以我们就要尽量走顶点。我们看一下,如果走最短边,那么下一次就会增加2的能到的块,如果走对角线,那么下一次就增加3的块。所以我们就要看走那边最好。然后暴力枚举。至于为什么是枚举到2,是因为你走的线路只有在一开始和最后会有所改变。(应该算是贪心)
代码:
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const double pai = acos(-1.0);
int main()
{
int t;
cin >> t;
while (t--) {
double w, d;
cin >> w >> d;
double a = min(w, d), b = sqrt(w * w + d * d);
ll ans = 0;
for (int i = 0; i <= 2; i++) {
if (pai - a * i >= 0) ans = max(ans, (ll)(4 + i*2 + (int)((pai-a*i)/b) * 3));
if (pai - b * i >= 0) ans = max(ans, (ll)(4 + i*3 + (int)((pai-b*i)/a) * 2));
}
cout << ans << endl;
}
}