Codeforces Round #694 (Div. 1) ABD

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串会变化

  1. 如果有偶数个数字“相邻”(题目所定义,下同),那么他们相乘之后必是一个平方数,01串会变成全0
  2. 如果有奇数个数字“相邻”(题目所定义,下同),那么他们相乘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 ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值