首页 > 其他分享 >AtCoder Beginner Contest 206(Sponsored by Panasonic)(E,F)

AtCoder Beginner Contest 206(Sponsored by Panasonic)(E,F)

时间:2023-05-09 20:45:40浏览次数:54  
标签:AtCoder gcd Beginner 206 int long include SG define

AtCoder Beginner Contest 206(Sponsored by Panasonic)(E,F)

E(容斥,gcd)

E

这个题大意就是给出一个\(l\)和一个\(r\),寻找满足以下条件的一对数\((x,y)\)的数量

\(gcd(x,y)!=1\)

\(gcd!=x\)并且\(gcd!=y\)(从这一句我们可以知道\(x\)不可能被\(y\)整除)

那么我们可以设\(x\)是\(t\)的倍数,\(y\)是\(t\)的倍数,先保证\(gcd(x,y)\)不为\(1\),

对于\([l,r]\)这一个区间可以是\(t\)的倍数的最小的数是\(\frac{l-1}{t}\times t\),最大的那个倍数是\(\frac{r}{t}\times t\),所以我们可以很简单的求出这个区间是\(t\)的倍数的数量\(cnt\),然后我们要让\(gcd(x,y)\)是\(t\)不仅要都要是\(t\)的倍数(\(w^2\),两个都从里面选),还可能会有\(gcd\)是\(2t\)等的,所以我们要减去那些可能是其他\(t\)的倍数的\(gcd\)的情况,用\(f[t]\)表示\(gcd\)是\(t\)的一对数的数量,那么需要减去\(f[2t]\)等等

然后我们再考虑第二句话的要求,\(x\)和\(y\)之间不能存在整除的关系,那么我们手动减去那些整除的一些

对于此时的\(gcd\)为\(t\)时,假设\(x=t\),那么存在可以是\(x\)的倍数的数有\(\frac{r}{x}\)个,同样假如\(y\)为\(t\)时,同样也是这么多,但是当\((t,t)\)只有一个,这里多计算了一次,需要减一

参考

具体可以看代码

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include<cmath>
#include <unordered_map>
#include <array>
#include <cstring>
using namespace std;
#define int long long 
#define LL long long
#define ios  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define inf 1e18
#define INF 1e18
#define mem(a,b) memset((a),(b),sizeof(a))
const double eps=1e-9;
const int maxn=1e6+10;
const int mod=1e9+7;
int  n;
int f[maxn],l,r;
signed main() 
{
   cin>>l>>r;
   l--;
   int ans=0;
   for (int i=r;i>=2;i--)
   {
      int w=r/i-l/i;//(l-1)/i这个数最小的x*i>=l
      f[i]=w*w;
      for (int j=i+i;j<=r;j+=i)
      {
         f[i]-=f[j];
      }
      ans+=f[i];
   }
   for (int i=l+1;i<=r;i++)
   {
      if(i==1) continue;
      int now=r/i;
      now=now*2-1;
      ans-=now;
   }
   cout<<ans<<"\n";
   system ("pause");
    return 0;
}

F(博弈,SG,记忆化)

F

这个题大意就是一个游戏,每个人都可以选择一个区间段,只要这一个区间没有和之前已经选过的区间重合即可,如果这个人选不出,那么这个人就输了

对于这一道题,就是用了\(sg\)函数和一些记忆化来写的

对于\(sg\)函数什么时候该用,什么时候不该用,我还不是很懂,之前也做过一次题,不过是通过打表得出规律的

例题

感觉这个人的解释还蛮清楚的,学习

其中给出了一个公式

\[SG(x)=mex(SG(y)|x\rightarrow y) \]

然后我们可以变化一下,得到

\[SG(l,r)=mex(SG(l,ll)\bigoplus SG(rr,r)|SG(l,r)\rightarrow SG(l,ll)和SG(rr,r)) \]

有了以上公式其他的都很好写了

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include<cmath>
#include <unordered_map>
#include <array>
#include <cstring>
using namespace std;
#define int long long 
#define LL long long
#define ios  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define inf 1e18
#define INF 1e18
#define mem(a,b) memset((a),(b),sizeof(a))
const double eps=1e-9;
const int maxn=100+10;
const int mod=1e9+7;
int  n;
vector<int>g[maxn];
int dp[maxn][maxn];
int find(int l,int r)
{
   if(l>r) return 0;
   if(dp[l][r]!=-1) return dp[l][r];
   set<int>st;
   for (int ll=l;ll<=r;ll++)
   {
      for (auto rr:g[ll])
      {
         if(rr<=r)
         {
            int now=find(l,ll)^find(rr,r);
            st.insert(now);
         }
      }
   }
   int now=0;
   for (auto x:st)
   {
      if(now==x)
      {
         now++;
      }
      else 
      {
         break;
      }
   }
   dp[l][r]=now;
   return dp[l][r];
}
void solve()
{
   cin>>n;
   for (int i=1;i<=100;i++)
   {
      g[i].clear();
   }
     memset(dp, -1, sizeof(dp));
   for (int i=1;i<=n;i++)
   {
     int l,r;
     cin>>l>>r;
      g[l].push_back(r);
   }
   if(find(1,100)>0)
   {
      cout<<"Alice\n";
   }
   else 
   {
      cout<<"Bob\n";
   }
   return ;
}
signed main() 
{
   int t;
   cin>>t;
   while (t--)
   {
      solve();
   }
   system ("pause");
    return 0;
}

标签:AtCoder,gcd,Beginner,206,int,long,include,SG,define
From: https://www.cnblogs.com/righting/p/17386208.html

相关文章

  • AtCoder Beginner Contest 217 G Groups
    洛谷传送门AtCoder传送门不妨钦定组之间的顺序是最小值越小的组越靠前,这样可以给每个组按顺序编号。设\(f_{i,j}\)为考虑了模\(m\)后\(<i\)的数,目前有\(j\)个非空组的方案数。转移就是枚举模\(m=i-1\)的数新开了\(k\)个组,设\(\len\)的数中模\(m=i-1......
  • [AtCoder-AT_ABC070C]题解(C++)
    PartIPreface原题目(Luogu)原题目(AtCoder)PartIISketch给定一个正整数\(N(1\leqN\leq100)\),表示时钟数量。接下来\(N\)行,每行一个正整数\(T_i(1\leqT_i\leq10^{18})\),表示每个时钟旋转\(T_i\)秒后还会回到原来的地方。求出在多少秒之后,所有时钟还会同时......
  • [AtCoder-AT_ABC070_A]题解(C++)
    PartIPreface原题目(Luogu)原题目(AtCoder)PartIISketch给定一个正整数\(n(100\leqn\leq999)\)。求\(n\)是否是一个回文数,是输出\(\texttt{Yes}\),不是输出\(\texttt{No}\)。PartIIIAnalysisSolve1如果仔细观察的话,应该都能发现,\(n\)一定是一个三位数。......
  • AtCoder Beginner Contest 209(D,E)
    AtCoderBeginnerContest209(D,E)D(树,lca)D这个题给出\(n\)个点,\(n-1\)条边,有两个人,一个人在\(c\)点,一个人在\(d\)点,两人以相同的速度朝着对方走来(并且都是按照最短路的走法),问这两个人相遇是在点上,还是在路上这一题意很好知道,就是判断这两点之间的最短距离的奇偶性然后我就一......
  • Atcoder Grand Contest 046 D - Secret Passage
    思路挺自然的一道agc。首先发现删除完字符后的状态可以用一个三元组\((i,j,k)\)表示,其中\(i\)表示删除完之后只剩\([i+1,n]\)的后缀,\(j\)表示可以在后面插入\(j\)个\(0\),\(k\)表示可以在后面插入\(k\)个\(1\),显然不同的三元组能够得到的串是不同的,而一组三元组可......
  • AtCoder Regular Contest 159简要题解
    AtCoderRegularContest159传送门A-CopyandPasteGraph图的邻接矩阵为\[\left(\begin{matrix}A&A&\cdots&A\\A&A&\cdots&A\\\cdots&\cdots&\cdots&\cdots\\A&A&\cdots&A\e......
  • AtCoder Regular Contest 134 E Modulo Nim
    洛谷传送门AtCoder传送门It'sallMAGIC这种题目一般先考虑局面要满足什么条件能必胜,然后根据这个性质来计数。如果把黑板上的数写成一个集合\(S\),那么:\(\varnothing\)为必胜态,\(\{1\},\{2\}\)显然为必败态,打表发现其他单元素集合都为必胜态;如果\(\existsx\inS,x......
  • AtCoder Beginner Contest 242
    A-T-shirt#include<bits/stdc++.h>usingnamespacestd;int32_tmain(){doublea,b,c,x; cin>>a>>b>>c>>x; if(x<=a)cout<<"1.000000000000"; elseif(x>b)cout<<&qu......
  • AtCoder Beginner Contest 285(B,D,E,F)
    AtCoderBeginnerContest285(B,D,E,F)B(暴力,非二分)B这道题其实很简单,但是我在\(vp\)的过程,有了一个错误的认识,纠正一下那就是,我把这个当成了一个二分题,并且还有点坚定不移,后来细想,发现不对二分,适用于那种边界分明的那种题(左边一定是符合条件,右边一定符合条件,也可表达为线性......
  • CPT206任务规范
    CPT206ComputerProgrammingforFinancialMathematics:Coursework3TaskSpecificationThomasSeligSet:Wednesday,3May,2023Duedate:Sunday,21May,2023,23:59ThisisthespecificationtasksheetfortheCoursework3assessmentcomponentofyourCPT206m......