E1 - Square-free division (easy version)(思维+平方数质因子分解+卡常)

https://codeforces.com/contest/1497/problem/E1


思路:

最开始是暴力3000的平方数每个对n里的进行除看有无除数,logn*n*3100 tle2.

优化:平方数只和其奇数指数的质因子有关,sqrt处理,然后map找因子。tle(102test)

两种方式优化:

TLE102test

改成hash手写可以考虑试试。我改防卡的没用。估计是卡stl了。

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+100;
typedef int LL;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
map<LL,LL>map1;
LL a[maxn];
LL solve(LL x){
    LL mul=1;
    for(LL i=2;i<=sqrt(x);i++){
        if(x%i==0){
            LL cnt=0;
            while(x%i==0){
                x/=i;
                cnt++;
            }
            if(cnt&1){
                mul*=i;
            }
        }
    }
    if(x>1) mul*=x;
    return mul;
}
int main(void)
{
  ///cin.tie(0);std::ios::sync_with_stdio(false);
  LL t;t=read();
  while(t--){
    LL n,k;n=read();k=read();
    map1.clear();
    for(LL i=1;i<=n;i++) a[i]=read();
    for(LL i=1;i<=n;i++) a[i]=solve(a[i]);
    LL ans=1;
    map1[a[1]]++;
    for(LL i=2;i<=n;i++){
        if(map1.count(a[i])){
            ans++;
            map1.clear();
        }
        map1[a[i]]++;
    }
    printf("%d\n",ans);
  }
return 0;
}

优化一:下面的方式改成双指针和数组查询。严格O1

一关找不到某紫名的代码了..参考就好,主要是下面的改双指针

#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
using namespace std;
typedef unsigned int ui;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef tuple<int, int, int> tiii;
typedef tuple<int, int, int, int> tiiii;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector <vector <int>> vvi;  
typedef vector<pii> vpii;
#define F(i, a, b) for(int i = (int)a; i <= (int)b; i++)
#define f(i, a, b) for(int i = (int)a; i >= (int)b; i--)
#define F2(i, a, b) for(int i = (int)a; i <= (int)b; i+=2)
#define f2(i, a, b) for(int i = (int)a; i >= (int)b; i-=2)
#define IN insert
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define RS resize
#define trans int tm = (tl + tr)>>1, l = v<<1, r = l|1
#define RBT tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update>
ld const PI = acos(-1);
 
 
int const N = 2e5 + 4, C = 1e7 + 1;
bool was[C];
int a[N];
 
int fac(int x) {
	int msk = 1;
	for (int i = 2; i * i <= x; ++i) {
		if (x % i)
			continue;
		bool cnt = 0;
		while (x % i == 0) {
			cnt = !cnt;
			x /= i;
		}
		if (cnt)
			msk *= i;
	}	
	if (x > 1)
		msk *= x;
	return msk;
}
 
void solve(){
	int n, k;
	cin >> n >> k;
	F(i, 1, n) {
		cin >> a[i];
		a[i] = fac(a[i]);
	}
	int l = 0;
	int ans = 0;
	while (l <= n) {
		int r = l;
		while (r <= n && !was[a[r]]) {
			was[a[r]] = 1;
			++r;
		}
		++ans;
		while (l < r) {
			was[a[l]] = 0;
			++l;
		}
	}
	cout << ans << '\n';
}
 
//#define LOCAL
int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	#ifdef LOCAL
	freopen("in", "r", stdin);
	freopen("out", "w", stdout);
	#endif     
	int t = 1;
	cin >> t;
	while(t--)
		solve();
	return 0;
}

方式二:

处理质数改成筛,欧拉筛处理最大质因子/最小质因子,log分解。200ms结束。map无压力

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<unordered_map>
#include<map>
#include<set>
#include<cstdio>
#include<chrono>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e7+100;
typedef int LL;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
map<LL,LL>map1;
LL a[maxn];
LL v[maxn],primes[maxn];
void getprimes(LL n)
{
	LL m=0;
	for(LL i=2;i<=n;i++){
		if(v[i]==0) {v[i]=i;primes[++m]=i;}
		for(LL j=1;j<=m;j++){
			if(primes[j]>v[i]||primes[j]>n/i)	break;
			v[i*primes[j]]=primes[j];
		}
	}
}
LL solve(LL x){
    LL mul=1;
    while(x>1){
        LL cnt=0;
        LL temp=v[x];
        while(x%temp==0){
            x/=temp;
            cnt++;
        }
        if(cnt&1) mul*=temp;
    }
    if(x>1) mul*=x;
    return mul;
}
int main(void)
{
  getprimes(10000000);
  LL t;t=read();
  while(t--){
    LL n,k;n=read();k=read();
    map1.clear();

    for(LL i=1;i<=n;i++) a[i]=read();
    
    for(LL i=1;i<=n;i++) a[i]=solve(a[i]);

    LL ans=1;
    map1[a[1]]++;
    for(LL i=2;i<=n;i++){
        if(map1.count(a[i])){
            ans++;
            map1.clear();
        }
        map1[a[i]]++;
    }
    printf("%d\n",ans);
  }
return 0;
}

猜你喜欢

转载自blog.csdn.net/zstuyyyyccccbbbb/article/details/114991973