首页 > 其他分享 >Codeforces Round 891 (Div. 3) A-G

Codeforces Round 891 (Div. 3) A-G

时间:2023-08-09 13:22:20浏览次数:31  
标签:891 a1 int res Codeforces len getx 数组 Div

偷偷摆烂导致小号掉了16分,但是队友涨了16分,一定是米哈游的问题!

A. Array Coloring

题意:给出一个长为\(n\)的数组,问能否把所有元素分别染成两种颜色中的一种,并且使得同种颜色的元素和它们最后的奇偶性相同。

Solution

算出奇数个数看是不是奇数个即可

void solve()
{
	int n;cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	int cnt0=0,cnt1=0;
	for(int i=1;i<=n;i++)
	{
		if(a[i]&1)cnt1++;
		else cnt0++;
	}
	if(cnt1&1)cout<<"NO\n";
	else cout<<"YES\n";
}

B. Maximum Rounding

题意:给出一个\(x\),可以进行任意次四舍五入操作,每次四舍五入的位置任选,问\(x\)进行若干次操作后最大是多少

Solution

从低位往高位一步步看即可

void solve()
{
	string s;cin>>s;
	int flag=0;
	int pos=-1;
	for(int i=s.length()-1;i>=0;i--)
	{
		if(s[i]-'0'>=5)
		{
			pos=i;
			if(i>0)s[i-1]++;
			else flag=1;
		}
	}
	if(pos>=0)
	for(int i=pos;i<s.length();i++)s[i]='0';
	if(flag)cout<<"1";
	cout<<s<<"\n";
}

C. Assembly via Minimums

题意:有一个长为\(n\)的数组\(a\),通过\(a\)可以得到长为\(\frac{n(n-1)}{2}\)数组\(b\),\(b\)数组的元素为\(a\)数组中任选两个不同的数,取其中的最小值得到,现在给出打乱的数组\(b\),求数组\(a\)

Solution

将\(b\)排序,从\(1\)开始每\(n,n-1,...,1\)个相同就是最小值,最后一个直接随便找个最大的即可

void solve()
{
	int n;cin>>n;
	for(int i=1;i<=n*(n-1)/2;i++)cin>>b[i];
	sort(b+1,b+1+n*(n-1)/2);
	int cnt=1;
	int pos=1;
	while(pos<=n*(n-1)/2)
	{
		a[cnt++]=b[pos];
		pos+=(n-cnt+1);
	}
	a[cnt]=b[n*(n-1)/2];
	for(int i=1;i<=n;i++)cout<<a[i]<<" \n"[i==n];
}

D. Strong Vertices

题意:给出两个数组\(a,b\),现在建立一张图,如果有\(a[u]-a[v]>b[u]-b[v]\),则有从\(u\)到\(v\)的一条有向边,问哪些点可以到其它所有点

Solution

交换发现\(a[u]-b[u]>a[v]-b[v]\)

所以建立一个新数组为\(a\)与\(b\)的差值数组,从大往小遍历看即可

struct node
{
	int x,y;
	bool operator <(const node&t)const &{
		if(x!=t.x)return x<t.x;
		else return y<t.y;
	}
}e[N];
void solve()
{
	int n;cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<=n;i++)cin>>b[i];
	for(int i=1;i<=n;i++)
	{
		//cout<<a[i]<<" "<<b[i]<<"\n";
		e[i].x=a[i]-b[i];
		//cout<<e[i].x<<"\n";
		e[i].y=i;
		//sort(e+1,e+1+n);
	}
	sort(e+1,e+1+n);
	//for(int i=1;i<=n;i++)cout<<e[i].x<<" \n"[i==n];
	int pos=0;
	for(int i=1;i<=n;i++)
	{
		if(e[i].x==e[n].x)
		{
			pos=i;break;
		}
	}
	cout<<n-pos+1<<"\n";
	for(int i=pos;i<=n;i++)
	{
		cout<<e[i].y<<" \n"[i==n];
	}
}

E. Power of Points

题意:给出一个若干个数\(x_1,...x_n\),对于整数\(s\),构造\(n\)个区间\([s,x_1],[s,x_2],...,[s,x_n]\),定义\(f_p\)为点\(p\)被包含的区间个数

现在求对于\(s\in\{x_1,...,x_n\}\),\(\sum_{p=1}^{10^9}f_p\)

Solution

其实就是求所有区间的长度,用前缀和处理一下就很容易得到答案了

struct node
{
	int x,y;
	bool operator <(const node&t)const &{
		if(x!=t.x)return x<t.x;
		else return y<t.y;
	}
}e[N];
void solve()
{
	int n;cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<=n;i++)
	{
		b[i]=a[i];
		e[i].x=a[i];
		e[i].y=i;
	}
	sort(b+1,b+1+n);
	sort(e+1,e+1+n);
	for(int i=2;i<=n;i++)b[i]+=b[i-1];
	for(int i=1;i<=n;i++)
	{
		ans[e[i].y]=n+(e[i].x*i-b[i])+(b[n]-b[i])-(e[i].x*(n-i));
	}
	for(int i=1;i<=n;i++)cout<<ans[i]<<" \n"[i==n];
}

F. Sum and Product

题意:给出一个数组\(a\),进行\(q\)次询问,每次询问找到满足以下要求的数对个数:

1.\(1\leq i<j\leq n\)

2.\(a_i+a_j=x,a_i \times a_j=y\)

其中\(x\)与\(y\)由询问给出

Solution

既然已知\(x,y\),可以直接算出\(a_i,a_j\),对\(a\)数组排序,然后二分找到满足答案的个数即可,注意判重

int getx(int x)
{
	int l=lower_bound(a+1,a+1+n,x)-a;
	if(l>n||a[l]!=x)return 0;
	int r=upper_bound(a+1,a+1+n,x)-a;
	r--;
	if(r>n||a[r]!=x)return 0;
	return r-l+1;
	
	
}
 
void solve()
{
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	sort(a+1,a+1+n);
	int q;cin>>q;
	while(q--)
	{
		int x,y;cin>>x>>y;
		int z=x*x-4*y;
		if(z<0)
		{
			cout<<"0 ";
			continue;
		}
		int l=sqrt(z);
		if(l*l!=z)
		{
			cout<<"0 ";
			continue;
		}
		int a1=x+l,a2=x-l;
		int res=0;
		if((x+l)%2==0)
		{
			a1/=2,a2/=2;
			int b1=x-a1;
			int b2=x-a2;
			if(a1>b1)swap(a1,b1);
			if(a2>b2)swap(a2,b2);
			if(a1==a2)
			{
				if(a1==b1)
				{
					int len=getx(a1);
					res+=len*(len-1)/2;
				}else res+=getx(a1)*getx(b1);
			}else
			{
				if(a1==b1)
				{
					int len=getx(a1);
					res+=len*(len-1)/2;
					res+=getx(a2)*getx(b2);
				}else if(a2==b2)
				{
					int len=getx(a2);
					res+=len*(len-1)/2;
					res+=getx(a1)*getx(b1);
				}
			}
			
		}
		
		cout<<res<<" ";
	}
	cout<<"\n";
}

G. Counting Graphs

题意:给出一棵树,问有多少张图,满足以下条件:

1.没有自环和重边

2.边权都不超过\(s\)

3.这个图有且仅有一棵最小生成树,并且这棵树是给出的树

Solution

考虑到最小生成树的条件,我们不难发现,假如我们要加入一条\(<u,v>\)的边,那么它的权值必须大于树上\(u\)到\(v\)经过的权值最大的边,所以我们可以通过kruskal重构树,遍历所有非叶子节点,它对答案的贡献为\((max(0,w[x]-s)+1)^{sz[lson]\times sz[rson]-1}\)

struct node
{
    int u, v, w;
    bool operator<(const node &t) const &
    {
        return w < t.w;
    }
};
int n, s;
vector<node> g;
vector<int> e[N << 1];
int t[N << 1];
int find(int x)
{
    return t[x] == x ? t[x] : t[x] = find(t[x]);
}
 
int idx = n;
int w[N<<1];
void kruskal() // kruskal重构树
{
    for (auto it : g)
    {
        int u = it.u, v = it.v, ww = it.w;
        int x = find(u), y = find(v);
       // cout<<x<<" "<<y<<"\n";
        if (x != y)
        {
            idx++;
            t[idx] = idx;
            t[x] = t[y] = idx;
            w[idx] = ww;
            //cout<<ww<<"\n";
            e[x].push_back(idx);
            e[y].push_back(idx);
            e[idx].push_back(x);
            e[idx].push_back(y);
        }
    }
}
int sz[N << 1];
 
int ans = 1;
int ksm(int x, int y, int mod1 = mod)
{
    int res = 1;
    x %= mod1;
    while (y > 0)
    {
        if (y & 1)
        {
            res = res * x % mod1;
        }
        y >>= 1;
        x = (x * x) % mod1;
    }
    return res;
}
void dfs(int x)
{
    if (x <= n)
    {
        sz[x] = 1;
        return;
    }
    int lson = e[x][0], rson = e[x][1];
    dfs(lson), dfs(rson);
    sz[x] = sz[lson] + sz[rson];
    ans = (ans * ksm(max(0LL, s - w[x]) + 1, (sz[lson] * sz[rson] - 1))) % mod;
}
 
void solve()
{
    ans = 1;
    cin >> n >> s;
    g.clear();
    for (int i = 1; i <= n; i++)
        t[i] = i;
    for(int i=1;i<=2*n;i++)e[i].clear();
    for (int i = 1; i < n; i++)
    {
        int u, v, w;
        cin >> u >> v >> w;
        g.push_back({u, v, w});
    }
    sort(g.begin(), g.end());
    idx = n;
    kruskal();
    dfs(idx);
    cout << ans << "\n";
}

标签:891,a1,int,res,Codeforces,len,getx,数组,Div
From: https://www.cnblogs.com/HikariFears/p/17616601.html

相关文章

  • Codeforces Round 891 (Div. 3)
    A.ArrayColoring#include<bits/stdc++.h>usingnamespacestd;voidsolve(){intn;cin>>n;intsum=0;for(inti=1,x;i<=n;i++)cin>>x,sum+=x;if(sum%2==0)cout<<&quo......
  • Codeforces Round 891 (Div. 3) 题解
    A.ArrayColoring因为:偶数+偶数=偶数奇数+奇数=偶数奇数+偶数=奇数所以设\(s1\)为奇数之和,\(s2\)为偶数之和\(s2\)必定是偶数如果奇数的个数为偶数,则\(s1\)为偶数;否则是奇数而在\(s1\)为奇数时,即使拿一个奇数加到\(s2\)里,那么也是不合法的所以直接判断奇数的......
  • Codeforces Round 891 (Div. 3)
    CodeforcesRound881(Div.3)A.ArrayColoring题目大意link思路简单判断数组和的奇偶性即可(小学数学)#include<bits/stdc++.h>usingnamespacestd;intmain(){intt;cin>>t;while(t--){intn;cin>>n;intsum=......
  • UESTC 2023 Summer Training #23 for div2/2022-2023 ACM-ICPC Latin American Region
    Preface今天这场签到巨多,和昨天那场形成了鲜明的对比但可惜后盘的时候我划了太久的水,最后接了B题然后没调出来成为战俘最气的是赛后发现原来是没注意输出格式,本来可以说一遍过的题结果没写过,属实可惜,就当长教训了以后一定要尤其注意输入输出格式A.AskingforMoneyORZ徐......
  • Codeforces Round 891 (Div. 3)
    CodeforcesRound891(Div.3)A-ArrayColoring思路:需要两部分的奇偶相同,判断奇数的个数是否为偶数即可#include<bits/stdc++.h>usingnamespacestd;#defineintlonglong//#defineint__int128#definedoublelongdoubletypedefpair<int,int>PII;typedefpair......
  • CodeForces CF1846G 题解
    CodeForcesCF1846G题解CodeForces题目链接洛谷题目链接标准答案是状压之后,转化成Dijkstra算法跑最短路。我这里提供一个不一样的思路。题意简述主人公得了病,有部分类型的症状。所有类型症状共有\(n\)种,用长为\(n\)的01串表示是否有那种症状。共有\(m\)种药,吃......
  • Codeforces 890-891的一些题目的反思
    和atcoder一起出交互题是吧。D题回复逆序对个数,对于[L,R-1]和[L,R],如果R是最大值,那么对逆序对个数无影响。这样来确认某个数是不是最大的,然后递归扩展到整个区间这里看到逆序对,要想到归并排序、分治、递归、区间合并。。。。。查看代码//Problem:D.MoreWrong//Contest......
  • B. Longest Divisors Interval
    link需要思考一下如果这个题能做,那么肯定有一种比较可行的做法。如果\([l,r]\)是可行的,那么就意味着\([1,r-l+1]\)是可行的这是显然的,显然后者的每一个数在前者中必然有对应的倍数,所以等效。这样从1开始找就行了。#include<cstdio>#include<iostream>#include<cstring>#i......
  • vue问题:不存在div或者多个div
    <el-radiov-model="radio"label="1">备选项</el-radio><el-radiov-model="radio"label="2">备选项</el-radio>报错:Errorscompilingtemplate:Componenttemplateshouldcontainexactlyonerootelement.......
  • codeforces 891 (div3)857E - Power of Points
    E.点的力量每个测试限时2秒每个测试限制内存为256兆字节输入以标准格式输入输出以标准格式输出给定n个具有整数坐标x1,…xn的点,这些点位于数线上。对于某个整数s,我们构建段[s,x1],[s,x2],…,[s,xn]。注意,如果xi<s,则段将类似于[xi,s]。段[a,b]覆盖了所有整数点a,a+1,a+2,…,b。......