Codeforces Round #694 (Div. 1) ABD
A
题目
思路
这种题就是我的弱项……我其实还不是很清楚这思路怎么来的
代码
#include <iostream>
#include <cstdio>
#include <set>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <string>
#include <sstream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <fstream>
using namespace std;
#define dbg(x) cerr << #x " = " << x <<endl;
typedef pair<int, int> P;
typedef long long ll;
const int MAXN = 3e5+5;
const int INF = 0x3f3f3f3f;
#define FIN freopen("in.txt", "r", stdin);
ll k[MAXN];
ll c[MAXN];
int vis[MAXN];
int cur = 0;
int main()
{
//FIN;
ios::sync_with_stdio(0);
int t;
cin >> t;
while(t--)
{
int n, m;
cin >> n >> m;
cur = 1;
memset(vis, 0, sizeof(int) * (m + 1));
for(int i = 1; i <= n; i++)
{
cin >> k[i];
}
for(int i = 1; i <= m; i++)
{
cin >> c[i];
}
sort(k+1, k +n+1);
ll sum = 0;
for(int i = n; i >= 1; i--)
{
if(cur <= k[i])
{
sum += c[cur++];
}
else
{
sum += c[k[i]];
}
}
cout << sum <<endl;
}
}
B
题目
思路
很容易得知x * y需要是平方数
然后我就不会了
下面是题解:
x * y是平方数,那唯一分解的时候就每个质数的质数都是偶数
那么对x和y分别唯一分解的时候,他们对应相同的质数的指数相加应该是偶数
唯一分解的形式为
x
=
p
i
a
i
∗
.
.
.
.
.
∗
x = {p_i}^{a_i} * .....*
x=piai∗.....∗,我们把
p
i
p_i
pi称为底
那么,对于x和y相同的底对应的指数,他们的奇偶性应该是一样的,这样才能保证相乘的时候底的指数是偶数
那么我们可以用01串表示每个数的唯一分解的各个底的指数的奇偶性
比如12 = 2 * 2 * 3,那么我们可以用01表示,0代表偶数,1代表奇数,2的2次方是偶数,就用0表示
再例如15 = 3 * 5,可以用011表示
我们发现,如果这个01串相同的数字,那么他们相乘必是平方数,也就是“相邻”
然后我们经过一次操作之后,这个01串会变化
- 如果有偶数个数字“相邻”(题目所定义,下同),那么他们相乘之后必是一个平方数,01串会变成全0
- 如果有奇数个数字“相邻”(题目所定义,下同),那么他们相乘01串不变
所以经过1s之后,能变的都变成0,剩下的都不会变,所以1s以后的状态和1s一样
开两个map,记录一下01串和状态数即可
(我这里没有记录01串,我的方法当幂次是奇数时,用一个字符串记录当前幂次,比如15 = 3 * 5,那么这个字符串就是“35”,如果是2 * 3 *3 * 5,那么字符串就是“25”(3的幂次是偶数,不记录),最后对这个字符串双hash)
代码
#include <iostream>
#include <cstdio>
#include <set>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <string>
#include <sstream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <fstream>
#include <iomanip>
#include <unordered_map>
using namespace std;
#define dbg(x) cerr << #x " = " << x << endl;
typedef pair<long long , long long> P;
typedef long long ll;
#define FIN freopen("in.txt", "r", stdin);
const int MAXN = 1e6+5;
int a[MAXN];
bool is[MAXN];
int prime[MAXN];
int tot = 0;
const int N = 300010;
const ll base = 21841;
const ll mod = 29050993;
const ll base2 = 1429;
const ll mod2 = 68861641;
void getprime()
{
memset(is, 1, sizeof(is));
is[0] = is[1] = 0;
for(int i = 2; i < MAXN; i++)
{
if(is[i])
{
prime[tot++] = i;
}
for(int j = 0; j < tot; j++)
{
if(i * prime[j] >= MAXN) break;
is[i * prime[j]] = 0;
if(i % prime[j] == 0) break;
}
}
}
map<P, int> m, m2;
P trans(int n)
{
string res = "";
int cur = 0;
ll sum1 = 0;
ll sum2 = 0;
while(n > 1)
{
if(is[n])
{
sum1 = (sum1 * base % mod + n) % mod;
sum2 = (sum2 * base2 % mod2 + n) % mod2;
break;
}
int cnt = 0;
while(n % prime[cur] == 0)
{
n /= prime[cur];
cnt++;
}
cnt %= 2;
if(cnt)
{
sum1 = (sum1 * base % mod + prime[cur]) % mod;
sum2 = (sum2 * base2 % mod2 + prime[cur]) % mod2;
}
cur++;
}
return P(sum1, sum2);
}
int main()
{
//FIN;
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
getprime();
int t;
cin >> t;
while(t--)
{
m.clear();
m2.clear();
int n;
cin >> n;
int Ans = -1;
for(int i = 0; i < n; i++)
{
cin >> a[i];
P op = trans(a[i]);
m[op]++;
Ans = max(Ans, (int)m[op]);
//dbg(a[i]);
//cout << op.first <<' ' << op.second <<endl;
//dbg(op);
}
//cout << "---------------------" << endl;
int ans2 = 0;
for(auto it = m.begin(); it != m.end(); it++)
{
//cout << it->first << ' ' << (it->second).size() << endl;
//cout << (it->first).first << ' ' << (it->first).second << " " << (it->second) << endl;
if((it->second) % 2 == 0 || (it->first).first + (it->first).second == 0)
{
ans2 += (it->second);
//dbg(ans2);
}
}
int q;
cin >> q;
while(q--)
{
ll qq;
cin >> qq;
int ans = Ans;
if(qq == 0)
{
cout << Ans << endl;
}
else
{
cout << max(Ans, ans2) << endl;
}
}
}
return 0;
}
D
思路
代码
#include<bits/stdc++.h>
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
int main()
{
ios ;
int T ;
cin >> T ;
while(T --)
{
int n , m ;
cin >> n >> m ;
vector<vector<int>> g(n + 1) ;
for(int i = 1 ; i <= m ; i ++)
{
int u , v ;
cin >> u >> v ;
g[u].push_back(v) ;
g[v].push_back(u) ;
}
function<bool()> can = [&]()
{
queue<int> q ;
q.push(1) ;
vector<bool> vis(n + 1 , false) ;
vis[1] = true ;
while(!q.empty())
{
int u = q.front() ;
q.pop() ;
for(auto v : g[u]) if(!vis[v]) vis[v] = true , q.push(v) ;
}
for(int i = 1 ; i <= n ; i ++) if(!vis[i]) return false ;
return true ;
} ;
if(!can())
{
cout << "NO\n" ;
continue ;
}
vector<int> c(n + 1 , -1) ;
function<void()> bfs = [&]()
{
queue<int> q ;
q.push(1) ;
c[1] = 1 ;
while(!q.empty())
{
int u = q.front() ;
q.pop() ;
bool flag = 0 ;
for(auto v : g[u]) if(c[v] == 1) flag = 1 ;
if(flag) c[u] = 0 ;
else c[u] = 1 ;
for(auto v : g[u]) if(c[v] == -1) q.push(v) , c[v] = 0 ;
}
} ;
bfs() ;
cout << "YES\n" ;
int cnt = 0 ;
for(int i = 1 ; i <= n ; i ++) if(c[i] == 1) cnt ++ ;
cout << cnt << '\n' ;
for(int i = 1 ; i <= n ; i ++) if(c[i] == 1) cout << i << ' ' ;
cout << '\n' ;
}
return 0 ;
}