首页 > 其他分享 >Codeforces Round 881 (Div. 3)

Codeforces Round 881 (Div. 3)

时间:2023-06-27 20:36:04浏览次数:38  
标签:881 int sum Codeforces rd dep maxN Div now

失踪人口回归

VP 打的

A. Sasha and Array Coloring

int n;
int a[maxN];

void solve(){
	n=rd();
	fp(i,1,n) a[i]=rd();
	sort(a+1,a+n+1);
	ll ans=0;
	for(int i=1;i*2<=n;++i)
		ans+=(a[n-i+1]-a[i]);
	cout << ans << endl;
}

B. Long Long

int n;
int a[maxN];
void solve(){
	n=rd();
	ll sum=0,last=1,step=0;
	fp(i,1,n){
		a[i]=rd();
		if(last==1&&a[i]<0) last=0,step++;
		else if(last==0&&a[i]>0) last=1;
		sum+=abs(a[i]);
	}
	cout << sum << " " << step << endl;
}

C. Sum in Binary Tree

ll n;
void solve(){
	ll n =lrd();
	ll sum=0;
	sum++;
	while(n!=1){
		sum+=n;
		n>>=1;
	}
	cout << sum << endl;
}

D. Apple Tree

const int maxN=2*1e5+10;
int n,q,idx;
int siz[maxN],dep[maxN],dfn[maxN];
ll leaf[maxN];
vector<int> g[maxN];

inline void dfs(int now,int f){
	dep[now]=dep[f]+1;
	dfn[now]=++idx;
	siz[now]=1;
	
	for(int x:g[now])
		if(x!=f) dfs(x,now),siz[now]+=siz[x],leaf[now]+=leaf[x];
	if(g[now].size()==1&&g[now][0]==f) leaf[now]=1;
}

void solve(){
	n=rd();
	fp(i,1,n-1){
		int u=rd(),v=rd();
		g[u].eb(v),g[v].eb(u);
	}
	dfs(1,1);
	q=rd();
	while(q--){
		ll ans=0;
		int a=rd(),b=rd();
		if(dep[a]>dep[b]) swap(a,b);
		if(dfn[a]<=dfn[b]&&dfn[b]<=dfn[a]+siz[a]-1){
			ans+=(ll)(leaf[a]-leaf[b])*leaf[b];
			ans+=(ll)leaf[b]*leaf[b];
		}
		else ans+=(ll)(leaf[a]*leaf[b]);
		cout << ans << endl;
	}
	met(siz,0);
	met(dep,0),met(dfn,0),met(leaf,0);
	idx=0;
	fp(i,1,n) g[i].clear();
}

E. Tracking Segments

一眼二分,没了

const int maxN=1e5+10;
int n,m,q;
int a[maxN],ch[maxN],pre[maxN];
pii line[maxN];

void solve(){
	n=rd(),m=rd();
	fp(i,1,m) line[i].first=rd(),line[i].second=rd();
	q=rd();
	fp(i,1,q) ch[i]=rd();
	int l=1,r=q,ans=-1;
	while(l<=r){
		int mid=(l+r)>>1;
		fp(i,1,mid) a[ch[i]]=1;
		fp(i,1,n) pre[i]=pre[i-1]+a[i];
		int flag=0;
		fp(i,1,m){
			int s=line[i].first,e=line[i].second;
			if((pre[e]-pre[s-1])*2>(e-s+1)){
				flag=1;break;
			}
		}
		met(a,0);
		met(pre,0);
		if(flag){
			ans=mid;
			r=mid-1;
		}
		else l=mid+1;
	}
	cout << ans <<endl;
}

F. Omsk Metro

动态给出一棵 \(n\)个节点的树,每个节点有一个权值,权值为 \(1\) 或 \(-1\),给出若干次询问,询问 \(u\),\(v\) 之间的路径上是否有一个子串的和为 \(k\)
\(n\in [1,10^5]\)

这里加一减一,则增长是连续的,所以我们要找到最大的和最小的子段和,然后判断是不是在这个区间里就可以了

这里使用了倍增实现

inline int logx(int n) {  
  int result = 0;  
  if(n&0xffff0000) {result += 16; n >>= 16; }  
  if(n&0x0000ff00) {result += 8; n >>= 8; }  
  if(n&0x000000f0) {result += 4; n >>= 4; }  
  if(n&0x0000000c) {result += 2; n >>= 2; }  
  if(n&0x00000002) {result += 1; n >>= 1; }  
  return result; 
}
const int maxN = 2 * 1e5 + 10;
int n;
int acc[maxN][20], dep[maxN], va[maxN], fa[maxN];
struct node {
	int minx, maxx;
	int mal, mar;
	int mil, mir, sum;
} f[maxN][20], g[maxN];

node update(node x, node y) {
	node z;
	z.mal = max(x.mal, y.mal + x.sum);
	z.mar = max(y.mar, x.mar + y.sum);
	z.mil = min(x.mil, y.mil + x.sum);
	z.mir = min(y.mir, x.mir + y.sum);
	z.minx = min(x.minx, min(y.minx, x.mir + y.mil));
	z.maxx = max(x.maxx, max(y.maxx, x.mar + y.mal));
	z.sum = x.sum + y.sum;
	return z;
}

void add(int x) {
	for (int i = 0, v = acc[x][i]; v; v = acc[x][++i]) acc[x][i + 1] = acc[v][i];
	dep[x] = dep[acc[x][0]] + 1;
	g[x].minx = min(va[x], 0), g[x].maxx = max(va[x], 0);
	g[x].mal = g[x].mar = max(0, va[x]);
	g[x].mil = g[x].mir = min(0, va[x]);
	g[x].sum = va[x];
	f[x][0] = g[x];z
	for (int i = 0, v = acc[x][i]; dep[x] >= (1 << (i + 1)); ++i,v = acc[x][i]){
		f[x][i + 1] = update(f[x][i], f[v][i]);
	} 
}

inline int lca(int x, int y) {
	if (dep[x] < dep[y]) swap(x, y);
	for (int gap = dep[x] - dep[y], bit = logx(gap); gap; gap -= (1<<bit), bit = logx(gap)) x = acc[x][bit];
	for (int i = logx(dep[x]); ~i; --i) if (acc[x][i] != acc[y][i]) x = acc[x][i], y = acc[y][i];
	return (x == y) ? x : acc[x][0];
}

node get_chain(int u, int c) {
	node ans;
	ans.sum=-inf;
	int flag = 0;
	for(int x=dep[u]-dep[c],bit=logx(x);x>0;x-=(1<<(bit)),bit=logx(x)) {
		if(!flag)
			ans=f[u][bit],flag=1;
		else 
			ans=update(ans,f[u][bit]);
		u=acc[u][bit];
	}
	return ans;
}

void M_clear(){
	node p=node{0,0,0,0,0,0,0};
	fp(i,1,n){
		va[i]=0,dep[i]=0,fa[i]=0;
		met(acc[i],0);
		fp(j,0,20) f[i][j]=p;
		g[i]=p;
	}
}

void solve() {
	int op = rd();
	dep[1] = 1;
	n = 1;
	va[1]=1;
	g[n].minx = min(va[n], 0), g[n].maxx = max(va[n], 0);
	g[n].mal = g[n].mar = max(0, va[n]);
	g[n].mil = g[n].mir = min(0, va[n]);
	g[n].sum = va[n];
	f[n][0] = g[n];
	while (op--) {
		char ch = getchar();
		if (ch == '+') {
			fa[++n] = rd();
			acc[n][0] = fa[n];
			va[n] = rd();
			add(n);
		} else {
			int u = rd(), v = rd(), k = rd();
			int c = lca(u, v);
			if (dep[u] < dep[v]) swap(u, v);
			node ans;
			if(c==u||c==v){
				ans=get_chain(u,c);
				if(ans.sum==-inf) ans=g[c];
				else ans=update(ans,g[c]);
			}
			else {
				ans=get_chain(u,c);
				ans=update(ans,g[c]);
				node p=get_chain(v,c);
				swap(p.mil,p.mir);
				swap(p.mar,p.mal);
				ans=update(ans,p);
			}
			if(ans.minx<=k&&ans.maxx>=k)
				cout << "YES" << endl;
			else cout << "NO" << endl;
		}
	}
	M_clear();
}

标签:881,int,sum,Codeforces,rd,dep,maxN,Div,now
From: https://www.cnblogs.com/Benzenesir/p/17509857.html

相关文章

  • Codeforces 1648F - Two Avenues
    为啥会有人觉得这是板子题啊/tuu先对图边双连通分量缩个点,然后考虑对两条边分情况讨论:两个桥边,显然答案就是经过这两个桥的路径数量之和,排序取前两大的即可。一个桥边加一个非桥边,答案是经过那个桥边的路径数量,显然桥边数量\(\ge2\)肯定不用考虑这种情况,桥边数量\(=1\)另......
  • maltab 利用不同方式(自编高斯赛德尔迭代函数,逆矩阵,左除(\)运算)求解线性方程组的速度
    参考:matlabhelp文档:mldivide实际测试比较,这里K_Tem为一个2398*2398的稀疏矩阵,Guass_Seidal是自己写的高斯赛德尔迭代函数 ......
  • CF1834 Div.2 做题记录
    A题面分类讨论即可点击查看代码#include<bits/stdc++.h>#defineullunsignedlonglong#definelllonglong#definepiipair<int,int>#definepdipair<double,int>#definepbpush_back#defineeps1e-9#definempmake_pairusingnamespacestd;namesp......
  • [LeetCode] 1071. Greatest Common Divisor of Strings
    Fortwostrings s and t,wesay"t divides s"ifandonlyif s=t+...+t (i.e., t isconcatenatedwithitselfoneormoretimes).Giventwostrings str1 and str2,return thelargeststring x suchthat x dividesboth str1 and str2.Exam......
  • CodeForces 605E Intergalaxy Trips 题解
    题意有一张\(n\)个点的有向完全图,边\(i\toj\)有\(p_{i,j}\)的概率出现(\(p_{i,i}=1\))。你要从\(1\)开始,每天可以走一条出边或留在原地,求最优策略下走到\(n\)的期望天数。输出小数(不取模)。\(n\le10^3\)思路设\(f(i)\)表示从\(i\)走到\(n\)的期望天数,那么......
  • CodeTON Round 5 (Div. 1 + Div. 2, Rated, Prizes!) C. Tenzing and Balls
    一开始以为是贪心,后来发现不好贪于是选择了dp,但是dp有个小细节没注意到,后面wa了几发我们以状态来分,f[i]表示考虑i的最大区间合长度,每次转移的时候考虑两种情况,一种是a[i]前面有一样的数字,比较选了a[i]和不选a[i]两种情况下的最大值,还有一种就是a[i]为第一个出现的数字则选区间长......
  • Codeforces 1787H - Codeforces Scoreboard(平衡树优化 dp)
    令\(c_i=b_i-a_i\),等价于我们钦定一个排列\(p\),最小化\(\sum\min(p_ik_i,c_i)\),拿\(\sumb_i\)减去之就是答案。我们钦定一些\(i\)满足\(p_ik_i<c_i\),根据排序不等式,这些\(p_i\)肯定按\(k\)从大到小的顺序依次填入\(1,2,3,\cdots\)。这样就可以DP了:将\(k\)从大......
  • CF Round 881 (Div. 3)
    CFRound881(Div.3)Div.3果然简单,虽然但是,我还是有1道题没有想出来。A.SashaandArrayColoring排序双指针向内即可。https://codeforces.com/contest/1843/submission/210855587B.LongLong好啊,就是这道题没想出来。VirtualContest上完成了一半。考虑把符......
  • Educational Codeforces Round 150 (Rated for Div. 2) A-E
    比赛链接A代码#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;boolsolve(){intn;cin>>n;if(n<=4)cout<<"Bob"<<'\n';elsecout<<"Alice"<<......
  • CodeForces 1842E Tenzing and Triangle
    洛谷传送门CF传送门一个很显然的观察:选择的三角形两两重叠面积为\(0\),否则合并更优。考虑dp,设\(f_i\)为删完\(x_j\gei\)的所有点的最小花费。转移就枚举选择的三角形直角边长\(l\),那么\(f_i=\min(f_{i+1}+\sum\limits_{x_p=i}c_p,\min\limits_lf_{i+l}......