AtCoder Beginner Contest 254(D-E)

Tasks - AtCoder Beginner Contest 254

D - Together Square

题意: 给定一个N,找出所有不超过N的 ( i , j ),使得( i * j )是一个平方数。

题解: 首先要知道一个数学只是,如果i*j是平方数,那么i*j /(f(i)*f(j))也是平方数  (f(j)表示的是j的不超过j的最大平方数因子),然后因为i/f(i)一定可以被质数 p分割两次或更多,所以得到 i/f(i)=j/f(j))

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int N=2e5+10;
const ll mod=1e9+7;
vector<ll> p,q;
ll n,t,cnt[N];
signed main(){
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin>>n;
  for(ll i=1;i*i<=n;i++){
    p.push_back(i*i);
  }
  for(ll i=1;i<=n;i++){
      ll f=*(upper_bound(p.begin(),p.end(),i)-1);//找到不超过i的最大的平方数
      if(i%f!=0){
        ll d=(ll)sqrt(f);
        while(i%f!=0){//判断是不是i的因子,不是就减
          d--;
          f=d*d;
        }
      }
      cnt[i/f]++;
  }
  ll ans=0;
  for(ll i=1;i<=n;i++) ans+=cnt[i]*cnt[i];
  cout<<ans;
}

 

 

E - Small d and k

题意: 一个无向图,每次询问一个点,与这个点距离不超过k的所有点的权值之和

题解: 暴力即可,注意每次vis的清零,不要用memset全部清零,会tle,可以存储一下所有走过的点,然后最后只将他们清空。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int N=3e5+5;
const ll mod=998244353;
const ll inf=1e18;
ll n,dp[N],m;
ll cnt,head[N*2],ans,vis[N];
struct ss{
  ll next,to;
}e[N*2];
void add(ll x,ll y){
  e[++cnt].to=y;
  e[cnt].next=head[x];
  head[x]=cnt; 
}
void bfs(ll beg,ll maxn){
  queue<pll> q;
  q.push({beg,0});
  vis[beg]=1;
  vector<ll> sum;
  sum.push_back(beg);
  while(!q.empty()){
    ll l=q.front().first;
    ll r=q.front().second;
    q.pop();
    if(r<=maxn) ans+=l;
    else continue;
    for(ll i=head[l];i;i=e[i].next){
      ll j=e[i].to;
      if(!vis[j]) vis[j]=1,sum.push_back(j),q.push({j,r+1}); 
    }
  }
  for(ll i=0;i<sum.size();i++) vis[sum[i]]=0;
}
signed  main(){
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin>>n>>m;
  for(ll i=1;i<=m;i++){
    ll x,y;cin>>x>>y;
    add(x,y); add(y,x);
  }
  ll t;cin>>t;
  while(t--){
    ll x,y;cin>>x>>y;
    ans=0;
    bfs(x,y);
    cout<<ans<<endl;
  }
}

 

posted @ 2022-07-08 20:43  HHzp  阅读(85)  评论(0)    收藏  举报