Codeforces-295记录

A

貌似有人用线段树做了...其实没必要 由于每次增加的是区间,而查询只是在最后进行一次,可以考虑在l处+1,r+1处-1,然后用前缀和的方式从头到尾扫一遍,比线段树还快。 如果是线段树的话,也应该最后再把lazy标记pushdown,可以提高效率。 codeforces816B也是同样的思路。

#include<cstdio>
#include<iostream>
using namespace std;
typedef long long LL;
const int N=120005;
LL init[N],l[N],r[N],d[N],ope[N],nar[N];
int main() {
	int n,m,k,a,b;
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=n;i++) scanf("%I64d",&init[i]);
	for(int i=1;i<=m;i++) scanf("%I64d%I64d%I64d",&l[i],&r[i],&d[i]);
	for(int i=1;i<=k;i++) {
		scanf("%d%d",&a,&b);
		ope[a]++;
		ope[b+1]--;
	}
	for(int i=1;i<=m;i++) {
		ope[i]+=ope[i-1];
		nar[l[i]]+=d[i]*ope[i];
		nar[r[i]+1]-=d[i]*ope[i];
	}
	for(int i=1;i<=n;i++) nar[i]+=nar[i-1];
	for(int i=1;i<=n;i++) printf("%I64d ",nar[i]+init[i]);
	return 0;
}

  

B

题意是逐个删除点,借用zzy大爷的说法:遇难则反 反过来操作,每次动态加入节点,然后用Floyd的思路维护距离和,注意顺序!!! 先更新新节点和原有节点之间的最短路,才能再把新节点当成中转节点更新原有节点内的最短路!

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=505;
LL G[N][N],ans[N];
int ord[N],n;
int main() {
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++) scanf("%I64d",&G[i][j]);
	for(int i=1;i<=n;i++) scanf("%d",&ord[i]);
	for(int i=n;i>=1;i--) {
		for(int j=i;j<=n;j++)
			for(int k=i;k<=n;k++) G[ord[k]][ord[i]]=min(G[ord[k]][ord[i]],G[ord[k]][ord[j]]+G[ord[j]][ord[i]]);
		for(int j=i;j<=n;j++)
			for(int k=i;k<=n;k++) G[ord[i]][ord[k]]=min(G[ord[i]][ord[k]],G[ord[i]][ord[j]]+G[ord[j]][ord[k]]);
		for(int j=i+1;j<=n;j++)
			for(int k=i+1;k<=n;k++) G[ord[j]][ord[k]]=min(G[ord[j]][ord[i]]+G[ord[i]][ord[k]],G[ord[j]][ord[k]]);
		for(int j=i;j<=n;j++)
			for(int k=i;k<=n;k++) ans[i]+=G[ord[j]][ord[k]];
	}
	for(int i=1;i<=n;i++)  printf("%I64d ",ans[i]);
	printf("\n");
	return 0;
}

  

C

第一眼就看出是动态规划,dp[i][j][k][l]表示第i步原来河岸仍有j个50kg的人,k个100kg的人,l为1则船在对岸,为0船在此岸。 然后动规即可,注意i要取到200为宜,注意边界,注意及时取模...

#include<cstdio>
#include<iostream>
using namespace std;
typedef long long LL;
const int N=51;
const LL mod=1e9+7;
int n,k,n1=0,n2=0;
LL dp[202][N][N][2],C[N][N];//dp[st][l1][l2][boat] boat=0->this;1->oppo l1,l2:this side
int main() {
	int x;
	scanf("%d%d",&n,&k);
	k/=50;
	for(int i=1;i<=n;i++) {
		scanf("%d",&x);
		if(x==50) n1++;
		else n2++;
	}
	for(int i=0;i<=n;i++) C[i][0]=1,C[i][i]=1;
	for(int i=2;i<=n;i++)
		for(int j=1;j<i;j++) {
			C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
		}
	dp[0][n1][n2][0]=1;
	for(int st=0;st<=200;st++) {
		if(dp[st][0][0][1]) {
			printf("%d\n%I64d\n",st,dp[st][0][0][1]);
			return 0;
		}
		for(int a1=0;a1<=n1;a1++) {
			for(int a2=0;a2<=n2;a2++) {
				if(dp[st][a1][a2][0]) {
					for(int u=0;u<=a1;u++) {
						if(u>k) break;
						for(int v=0;v<=a2;v++) {
							if(u+v*2>k) break;
							if(u+v==0) continue;
							dp[st+1][a1-u][a2-v][1]+=(C[a2][v]*(dp[st][a1][a2][0]*C[a1][u])%mod)%mod;
							dp[st+1][a1-u][a2-v][1]%=mod;
						}
					}
				}
				if(dp[st][a1][a2][1]) {
					for(int u=0;u<=n1-a1;u++) {
						if(u>k) break;
						for(int v=0;v<=n2-a2;v++) {
							if(u+v*2>k) break;
							if(u+v==0) continue;
							dp[st+1][a1+u][a2+v][0]+=(C[n2-a2][v]*(dp[st][a1][a2][1]*C[n1-a1][u])%mod)%mod;
							dp[st+1][a1+u][a2+v][0]%=mod;
						}
					}
				}
			}
		}
	}
	printf("-1\n0\n");
	return 0;
}

  

D

coming soon

E

线段树更改,先全部读进来离散化,然后操作 我们在线段树中维护以下值: num:该区间有多少个点。 sum:该区间点的横坐标之和。 ans :该区间每一对点的距离之和。 有了上面的量,下面关键的一点就是合并,其实很容易,设当前区间为t[p],其左子树为t[ls],右子树为[rs],则: t[p].sum=t[ls].sum+t[rs].sum t[p].num=t[ls].num+t[rs].num t[p].ans=t[rs].sumt[ls].num-t[rs].numt[ls].sum+t[ls].ans+t[rs].ans 貌似Anoxx是在线离散的,妙啊dalao.

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=110000;
LL init[N],tab[N*2],ope[N][3],ch[N],h[N],num[N*8],sum[N*8],ans[N*8],nn,ss,aa;
bool ini[N*2];
int sz=0;
inline void Update(int x,int l,int r) {
	if(l==r) return;
	int lc=(x<<1),rc=lc+1;
	sum[x]=sum[lc]+sum[rc];
	num[x]=num[lc]+num[rc];
	ans[x]=ans[lc]+ans[rc]+num[lc]*sum[rc]-num[rc]*sum[lc];
}
inline void Build(int x,int l,int r) {
	if(l==r) {
		if(ini[l]) {
			num[x]=1;sum[x]=tab[l];ans[x]=0;
		}
		return;
	}
	int mid=(l+r)>>1,lc=(x<<1),rc=lc+1;
	Build(lc,l,mid);
	Build(rc,mid+1,r);
	Update(x,l,r);
}
inline void Insert(int x,int l,int r,int pos,int tp) {
	if(l==r) {
		if(tp==1) {
			num[x]=1;sum[x]=tab[l];ans[x]=0;
		} else num[x]=sum[x]=ans[x]=0;
		return;
	}
	int mid=(l+r)>>1;
	if(pos<=mid) Insert(x<<1,l,mid,pos,tp);
	else Insert(x<<1|1,mid+1,r,pos,tp);
	Update(x,l,r);
}
inline void Query(int x,int l,int r,int a,int b) {
	if(l>r) return;
	if(l==a&&r==b) {
		aa=aa+ans[x]+nn*sum[x]-num[x]*ss;
		nn+=num[x];ss+=sum[x];
		return;
	}
	if(l==r) return;
	int mid=(l+r)>>1;
	if(b<=mid) Query(x<<1,l,mid,a,b);
	else if(a>mid) Query(x<<1|1,mid+1,r,a,b);
	else Query(x<<1,l,mid,a,mid),Query(x<<1|1,mid+1,r,mid+1,b);
}
int main() {
	int n,q;
	scanf("%d",&n);
	for(int i=1;i<=n;i++) {
		scanf("%I64d",&init[i]);
		tab[i]=ch[i]=h[i]=init[i];
	}
	sz=n;
	scanf("%d",&q);
	for(int i=1;i<=q;i++) {
		scanf("%I64d%I64d%I64d",&ope[i][0],&ope[i][1],&ope[i][2]);
		if(ope[i][0]==1) {
			ch[ope[i][1]]+=ope[i][2];
			tab[++sz]=ch[ope[i][1]];
		}
	}
	sort(init+1,init+n+1);
	sort(tab+1,tab+sz+1);
	unique(tab+1,tab+sz+1);
	for(int i=1;i<=sz;i++) if(tab[i]>tab[i+1]) sz=i;
	int p=1;
	for(int i=1;i<=n;i++) {
		while(tab[p]!=init[i]&&p<=sz) p++;
		ini[p]=1;
	}
	Build(1,1,sz);
	int l,r;
	for(int i=1;i<=q;i++) {
		if(ope[i][0]==2) {
			l=std::lower_bound(tab+1,tab+sz+1,ope[i][1])-tab;
			while(tab[l]<ope[i][1]&&l<=sz) l++;
			if(l==0) l=1;
			if(l>sz) {
				printf("0\n");
				continue;
			}
			r=std::lower_bound(tab+1,tab+sz+1,ope[i][2])-tab;
			if(r>sz) r=sz;
			while(tab[r]>ope[i][2]&&r>=1) r--;
			if(r<=0) {
				printf("0\n");
				continue;
			}
			nn=ss=aa=0;
			Query(1,1,sz,l,r);
			printf("%I64d\n",aa);
		} else {
			l=std::lower_bound(tab+1,tab+sz+1,h[ope[i][1]])-tab;
			h[ope[i][1]]+=ope[i][2];
			r=std::lower_bound(tab+1,tab+sz+1,h[ope[i][1]])-tab;
			Insert(1,1,sz,l,-1);
			Insert(1,1,sz,r,1);
		}
	}
	return 0;
}

  

时间: 2024-12-29 06:41:38

Codeforces-295记录的相关文章

【Codeforces Round 521】Codeforces #295(div. 1)

521A DNA Alignment 题意:给一个字符串\(s\),求有多少个\(t\)使得\(\rho(s,t)\)最大. 其中,\(t\)是一个和\(s\)等长的串, \(\rho(s,t)=\max_{i=0}^{n-1}\max_{j=0}^{n-1}h(shift(s,i),shift(t,i))\) \(h(s,t)=\sum_{i=0}^ns_i\ne t_i\) \(shift(s,i)=s_{i+1\dots n}+s_{1\dots i}\) 思路:首先我们看最大的答案是多少

Codeforces #295(Div 2) A Pangram、B Two Buttons、C DNA Alignment

A #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <map> #include <set> #include <vector> using namespace std; int A[50]; int main() { int n; string s; cin>>n; cin>&g

CodeForces - 471D MUH and Cube Walls

CodeForces - 471D 记录差分,利用kmp对分别除去了第一个数的两个数组进行匹配 注意特判模式串长度为一的情况 1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 5 const int maxn = 2e5 + 10; 6 int ans, n, m; 7 8 void find_substring(int pattern[], int text[]) { 9 vector<int

《退役的你》

视频:https://www.bilibili.com/video/av19333297 改编自高晓松<同桌的你> 伴奏为金池演唱版本 填词/视频/后期:Menci 演唱者 成都七中 王修涵 wxh010910 淮阴中学 杨乾澜 yanQval 常州一中 孔瑞阳 krydom 余姚中学 徐泽涛 NiroBC 中山纪中 王之栋 WerKeyTom_FTD 郑州一中 孟良谕 __stdcall 安师大附中 曾致远 Created_equal 安师大附中 朱震霆 whzzt 长乐一中 王颖 wy16

Codeforces 453B Little Pony and Harmony Chest:状压dp【记录转移路径】

题目链接:http://codeforces.com/problemset/problem/453/B 题意: 给你一个长度为n的数列a,让你构造一个长度为n的数列b. 在保证b中任意两数gcd都为1的情况下,使得 ∑|a[i]-b[i]|最小. 让你输出构造的数列b. (1<=n<=100, 1<=a[i]<=30) 题解: 因为1<=a[i]<=30,所以有1<=b[i]<=60,此时才有可能最优. 因为b中任意两数gcd为1,所以对于一个质因子p[i]

Codeforces 刷题记录

Codeforces 每日刷题记录 打'+'是一些有启发意义的题目,部分附上一句话题解,每日更新3题,大部分题目较水. 1.+CF1073E:状压,数位dp,官方题解std骚操作 2.CF1072A 3.CF1072B 4.CF1072C 5.CF1068C:读题恶心 6.CF1073D:猜复杂度,模拟 7.CF1088A 8.CF1088B 9.CF1088C:构造思想 10.CF1066A 11.CF1066B 12.CF1066C 13.+CF1088E:推结论,tree dp,贪心 14

codeforces 乱做题记录

Codeforces 590 E https://codeforces.com/problemset/problem/590/E 给 $ n $ 个只包含字符 $ a $ 和 $ b $ 的字符串,总长度不超过 $ 10^7 $,选出最多的字符串,使得其中不存在字符串 $ a $ 和 $ b $ 满足 $ a $ 是 $ b $ 的子串,输出方案,如果有多种方案,输出任意一种 $ n \le 750 $ 我们需要对每个串求出所有的比它短的是它的子串的字符串,并向其连边,可以发现这 $ n $ 个

Codeforces Round #575 (Div. 3)记录

Codeforces Round #575 (Div. 3)记录 错过了上分的机会,上次不小心打了个div. 2结果直接掉了100多分. 我绿了,也变弱了.找下场Div. 3上上分吧. A 随便写了. 我的思路是三个东西先排序,一个人先拿最少的,另一个人拿次少的. 然后看剩下的能不能填补相差,如果能的话继续左右两边各补,补到剩1或0为止. 其实上面说这么多,答案就等于\(\lfloor \frac{a+b+c}{2} \rfloor\). 我是sb B 这些数与大小无关,我们直接统计有多少个奇数

【cf比赛记录】Codeforces Round #600 (Div. 2)

Codeforces Round #600 (Div. 2) ---- 比赛传送门 昨晚成绩还好,AC A,B题,还能上分(到底有多菜) 补了C.D题,因为昨晚对C.D题已经有想法了,所以补起题来也快.(C题TLE了,D题想用并查集没好) A // http://codeforces.com/contest/1253/problem/A /* 如果YES,则b[i] - a[i] 在一个区间里的差肯定是相同的且不小于0 */ #include<iostream> #include<cst

【cf比赛记录】Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4)

比赛传送门 只能说当晚状态不佳吧,有点头疼感冒的症状.也跟脑子没转过来有关系,A题最后一步爆搜没能立即想出来,B题搜索没有用好STL,C题也因为前面两题弄崩了心态,最后,果然掉分了. A:简单数学 B:数学+排序 C:字符串搜索 A // https://codeforces.com/contest/1277/problem/A /* 题意: 给出一个数,求不大于该数的完美整数的个数(完美整数指全是一个数组成的数字,如:111, 333333, 444444, 9, 8888 ...) 分析: