[思维]Codeforces Round #596 (Div. 2, based on Technocup 2020 Elimination Round 2) A B1 B2 C D

A.给定两个数字的开头的第一位字符,问能不能凑成两个数字使得x = y + 1

while(cin >> a >> b)
{
	if(a == 9 && b == 1) { cout << "99 100" << '\n'; return 0; }
	if(a == b) { cout << a << '1' << ' ' << b << '2' << '\n'; }
	else if(a == b - 1)	{ cout << a << '9' << ' ' << b << '0' << '\n'; }
	else { cout << "-1\n"; }
}

B2 - TV Subscriptions (Hard Version)

问长度为k的区间内不同数字的数量,考虑枚举滑窗并记录cnt,当cnt从0变1的时候滑窗内贡献+1,当cnt从1变0时滑窗内贡献减一,但是组数很多对于使用过的数字应离散清空,用多少清多少,或者局部申请map计数,不然会tle

ll arr[MAXN] = {0};
int main()
{    
	//ios::sync_with_stdio(0);
	//cin.tie(0); cout.tie(0);
	int t;
	cin >> t;
	while(t--)
	{
		int n, k, d;
		cin >> n >> k >> d;
		for(int i = 0; i < n; ++i)
			cin >> arr[i];
		map <int, int> cnt;
		ll ans = 0, rans = INF;
		for(int i = 0; i < n; ++i)
		{
			if(i >= d)
			{
				--cnt[arr[i - d]];
				if(cnt[arr[i - d]] == 0)
					--ans;
			}
			if(cnt[arr[i]] == 0)
				++ans;
			++cnt[arr[i]];
			if(i >= d - 1) { rans = min(rans, ans); }
		}
		cout << rans << '\n';
	}
    return 0;
}

 C - p-binary 

问组成k的p二进制是最少几位,p二进制为每个二进制位的值变为2的k次方-p

考虑从小到大枚举位数,对于给定的位数x,需要用n减去x * p,然后凑二进制n即可

对于n有两个限制条件,第一n必须大于x,因为x位的数最小是x个1,

并且如果数字值大于项数的个数则肯定能凑够n项,第二 n需要大于0 负数二进制没法凑

ll pre[50] = {1};
 
int main()
{    
	//ios::sync_with_stdio(0);
	//cin.tie(0); cout.tie(0);
	for(int i = 1; i < 40; ++i)
	{ pre[i] = pre[i - 1] * 2; }
	ll n, p;
	cin >> n >> p;
	for(int i = 0; i <= 32; ++i)
	{
		ll rx = n - (i * p);
		if(rx < 0) break;
		int cnt = 0;
		ll py = rx;
		while(rx)
		{
			if(rx & 1) 
				++cnt;
			rx >>= 1;
		}
		if(cnt <= i && py >= i)
		{
			cout << i << '\n';
			return 0;
		}
	}
	cout << "-1\n" << '\n';
    return 0;
}
D

Power Products

 给定一个序列,问乘积为x的k次方的对数

k < 100\ arr[i] <= 1e5

考虑x^k有什么特性

x^k进行分解 必定有p1^{x1}*p2^{x2}*p3^{x3}*p4^{x4} = x^k

p均为素数,且次幂%k均为0 因为 a^3*b^3=(a*b)^3

那么对一个数的所有素因子拆分,并将其次幂%k,对于当前数字他需要的就是k - (次幂%k)

满 x^k 啥的啥也不需要

map<vector<pair<int,int>,int>记录当前位置前每个数的素因子和次幂和出现次数,然后对需要的进行统计即可

/*
    Zeolim - An AC a day keeps the bug away
*/
 
//#pragma GCC optimize(2)
//#pragma GCC ("-W1,--stack=128000000")
#include <bits/stdc++.h>
using namespace std;
#define mp(x, y) make_pair(x, y)
#define fr(x, y, z) for(int x = y; x < z; ++x)
#define pb(x) push_back(x)
#define mem(x, y) memset(x, y, sizeof(x))
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef std::pair <int, int> pii;
typedef std::vector <int> vi;
//typedef __int128 ill;
const ld PI = acos(-1.0);
const ld E = exp(1.0);
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MOD = 386910137;
const ull P = 13331; 
const int MAXN = 1e6 + 10;

map <vector<pii>, int> MP;

int arr[MAXN] = {0};

int main()
{  
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    //freopen("d:\out.txt","w",stdout);
    //freopen("d:\in.txt","r",stdin);
    	
    int n, k;
    cin >> n >> k;
    for(int i = 0; i < n; ++i)
    	cin >> arr[i];
    ll ans = 0;
    for(int i = 0; i < n; ++i)
    {
    	vector <pii> a, b;
    	int x = arr[i];
    	for(int j = 2; j * j <= x; ++j)
    	{
    		int cnt = 0;
    		while(x % j == 0) { x /= j; ++cnt; }
    		if(cnt % k == 0) continue; //不需要的直接不统计
			a.pb( mp (j, cnt % k) );
		}
		if(x != 1) a.pb(mp(x, 1)); //1没用 大家都有1
		sort( a.begin(), a.end() );
		for(auto now : a)
		{
			if(k - now.second) b.pb(mp(now.first, k - now.second)); //有余数才需要 不然不需要
		}
		ans += MP[b];
		MP[a]++;
	}
	
	cout << ans << '\n';
	
    return 0;
}

 

posted @ 2019-10-28 20:50  张浦  阅读(99)  评论(0编辑  收藏  举报