ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2021暑假牛客多校3

2021-07-31 21:57:51  阅读:113  来源: 互联网

标签:return int ll ++ long 多校 牛客 2021 include


B.Black and white

题意:
一个nxm的白色棋盘,在上边放上黑棋,放黑棋是有代价的,但是如果两行两列的四个焦点中有三个已经放上了,另外一个可以不花费任何代价放上该枚棋子,问放满棋盘的最小代价为多少?
A(i+1) = (Ai * Ai * b + Ai * c + d)% p
Where A(m*(i-1)+j) is the cost c(i, j)

主要思路:
根据题目要求先求出来每个位置的棋子代价(不要开数组,会越界)。然后分析可得,可以将行和列看作是点,放上一个棋子就相当于将i,j加入一个集合中。若某个棋子的i,j已经为一个集合了,则不用花费代价。

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pa;
const int N=1e6+10;
vector<pa> a[N];
int f[N];
int find(int k)
{
    if(f[k]==k) return k;
    return f[k]=find(f[k]);
}
int main()
{
    int n,m,b,c,d,p;
    ll aaa;//注意数据范围
    cin>>n>>m>>aaa>>b>>c>>d>>p;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            aaa=(aaa*aaa%p*b+aaa*c%p+d)%p;
            a[aaa].push_back({i,j+n});
        }
    }
    int ans=0;
    for(int i=0;i<=m+n;i++) f[i]=i;
    for(int i=0;i<=p;i++)
    {
        for(int j=0;j<a[i].size();j++)
        {
            int x=a[i][j].first,y=a[i][j].second;
            if(find(x)!=find(y))
            {
                f[find(x)]=find(y);
                ans+=i;
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

E.Math

题意:
给定一个n,问从 1~n 满足 x y + 1 ∣ x 2 + y 2 xy+1|x^2+y^2 xy+1∣x2+y2(1≤x≤y≤n)的数量。

主要思路:
利用韦达定理,推理出规律(也可打表),利用二分,求出答案。

公式推理:
令x为常数,利用韦达定理可得:
x 2 + y 2 = k ( x y − 1 ) x^2+y^2=k(xy-1) x2+y2=k(xy−1)
y 1 + y 2 = k x , y 1 ∗ y 2 = x 2 y_1+y_2=kx , y_1*y_2=x^2 y1​+y2​=kx,y1​∗y2​=x2
设 x ≤ y 1 x\leq y_1 x≤y1​,则 0 ≤ y 2 0\leq y_2 0≤y2​.
设 y = k x y=kx y=kx,可得 x 2 + k 2 y 2 = k ( k x 2 + 1 ) , k = x 2 x^2+k^2y^2=k(kx^2+1),k=x^2 x2+k2y2=k(kx2+1),k=x2.
由此可得答案应都形为:
( x , y )   ( x , x 3 )   ( x 2 − 1 , x 4 − x 2 ) . . . . . . . (x,y)~(x,x^3)~(x^2-1,x^4-x^2)....... (x,y) (x,x3) (x2−1,x4−x2).......

!!!注意数据类型,不可为unsigned long long (刚好为1e18,会使判断y大小的条件失效)

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef __int128 ull;
vector<ull> v;
int main()
{
    int t;
    cin>>t;
    for(long long  i=2;i<=1e6;i++)
    {
        ull y=i*i*i,x=i,k=i*i;
        v.push_back(y);
        while(y<=1e18)
        {
            ull xx=y;
            y=k*y-x;
            x=xx;
            if(y<=1e18)
                v.push_back(y);
        }
    }
    sort(v.begin(),v.end());
    while(t--)
    {
        long long n;
        cin>>n;
        cout<<upper_bound(v.begin(), v.end(),n)-v.begin()+1<<endl;
    }
    return 0;
}

F.24dian

题意:
选取n张值(1 ≤ x ≤ 13 \leq x\leq 13 ≤x≤13)的牌,进行四则运算后(可随意加括号),结果为m的情况,输出(式子中出现小数的)情况数,并且输出每种情况选择的牌。

主要思路:
该题是一个比较复杂的dfs模拟,需要合理利用各种容器。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
const int N=1e6+10;
vector<double> ans[N];
int n,m;
int num;
vector<double> v;
int flag,cnt;
bool judge(double x,double y)
{
    double xx=x/y;
    int xxx=xx;
    if(xx!=xxx) return 1;
    return 0;
}
void dfss(int x,int qwq,vector<double> v)//bianlifuhao
{
    if(x==n)//符号已满
    {
        if(fabs(v[0]-m)<1e-8)
        {
            flag++;
            if(qwq) cnt++;
        }
        return;
    }
    int sz=v.size();
    for(int i=0;i<sz;i++)
    {
        for(int j=0;j<sz;j++)
        {
            if(i==j) continue;
            vector<double> tmp;
            tmp.clear();
            for(int k=0;k<sz;k++)
                if(k!=i&&k!=j)
                    tmp.push_back(v[k]);
                    
            tmp.push_back(v[i]+v[j]);
            dfss(x+1,qwq,tmp);
            tmp.pop_back();
            tmp.push_back(v[i]-v[j]);
            dfss(x+1,qwq,tmp);
            tmp.pop_back();
            tmp.push_back(v[i]*v[j]);
            dfss(x+1,qwq,tmp);
            tmp.pop_back();
            tmp.push_back(v[i]/v[j]);
            dfss(x+1,qwq|judge(v[i],v[j]),tmp);
            tmp.pop_back();
        }
    }
}
bool check(vector<double> v)
{
    flag=0,cnt=0;
    dfss(1,0,v);
    if(flag==cnt&&cnt) return 1;
    return 0;
}
void dfs(int x,int pre)//bianlipai
{
    if(x==n+1)//排满
    {
        if(check(v))
            ans[num++]=v;
        return;
    }
    for(int i=pre;i<=13;i++)
    {
        v.push_back(i);
        dfs(x+1,i);
        v.pop_back();
    }
}
int main()
{
    cin>>n>>m;
    dfs(1,1);
    cout<<num<<endl;
    for(int i=0;i<num;i++)
    {
        int sz=ans[i].size();
        for(int j=0;j<sz;j++) cout<<ans[i][j]<<' ';
        cout<<endl;
    }
    return 0;
}

J.Counting Triangles

题意:
给定一个无向完全图,每条边都染上黑色或白色,问三条边同色的三角形数量。

主要思路:
三角形仅有两种:①三边同色 ②异色,且含有两个异色角。
然后难点是如何计算异色角的个数。答案为三角形总数-异色角数/2
异色角数求法:
若边ij为黑色 b[i]++,b[j]++
若为白色 w[i]++,w[j]++
在i点处的异色角数即为:b[i]*w[i]

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;

namespace GenHelper
{
    unsigned z1,z2,z3,z4,b,u;
    unsigned get()
    {
        b=((z1<<6)^z1)>>13;
        z1=((z1&4294967294U)<<18)^b;
        b=((z2<<2)^z2)>>27;
        z2=((z2&4294967288U)<<2)^b;
        b=((z3<<13)^z3)>>21;
        z3=((z3&4294967280U)<<7)^b;
        b=((z4<<3)^z4)>>12;
        z4=((z4&4294967168U)<<13)^b;
        return (z1^z2^z3^z4);
    }
    bool read() {
      while (!u) u = get();
      bool res = u & 1;
      u >>= 1; return res;
    }
    void srand(int x)
    {
        z1=x;
        z2=(~x)^0x233333333U;
        z3=x^0x1234598766U;
        z4=(~x)+51;
      	u = 0;
    }
}
using namespace GenHelper;
bool edge[8005][8005];
int main() {
    int b[8010]={0},w[8010]={0};
  int n, seed;
  cin >> n >> seed;
  srand(seed);
  for (int i = 0; i < n; i++)
    	for (int j = i + 1; j < n; j++)
        {
        	edge[j][i] = edge[i][j] = read();
            if(edge[i][j]) w[i]++,w[j]++;
            else b[i]++,b[j]++;
        }
    ll sum=0;
   ll ans=(ll)n*(ll)(n-1)*(ll)(n-2)/(ll)6;
    for(int i=0;i<n;i++)
        sum+=b[i]*w[i];
    cout<<ans-sum/2<<endl;
 	return 0;
}

标签:return,int,ll,++,long,多校,牛客,2021,include
来源: https://blog.csdn.net/weixin_54385104/article/details/119175513

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有