把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

Educational Codeforces Round 101 (Rated for Div. 2)

A
考虑无解的情况。显然\(n\)为奇数无解,然后\()\)在开头,\((\)在结尾无解。
然后似乎没有其它反例了。
于是就过了。
code:

#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define ll long long
#define db double
#define N 100
#define M 200000
#define mod 998244353
#define eps (1e-7)
#define U unsigned int
#define IT set<ques>::iterator
#define Gc() getchar() 
#define Me(x,y) memset(x,y,sizeof(x))
using namespace std;
int n,T,flag;char s[N+5];
int main(){
	re int i,j;scanf("%d",&T);while(T--){
		scanf("%s",s+1);n=strlen(s+1);printf("%s\n",((n&1)||s[1]==')'||s[n]=='(')?"NO":"YES");
	}
}

B
\(f_{i,j}\)为第一个序列到了\(i\),第二个序列到了\(j\)的最大值,随便转移即可。复杂度\(O(Tn^2)\)
code:

#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define ll long long
#define db double
#define N 100
#define M 200000
#define mod 998244353
#define eps (1e-7)
#define U unsigned int
#define IT set<ques>::iterator
#define Gc() getchar() 
#define Me(x,y) memset(x,y,sizeof(x))
using namespace std;
int n,m,T,flag,A[N+5],B[N+5],dp[N+5][N+5];
int main(){
	freopen("1.in","r",stdin);
	re int i,j;scanf("%d",&T);while(T--){
		scanf("%d",&n);for(i=1;i<=n;i++) scanf("%d",&A[i]),A[i]+=A[i-1];scanf("%d",&m);for(i=1;i<=m;i++) scanf("%d",&B[i]),B[i]+=B[i-1];
		Me(dp,-0x3f);dp[0][0]=0;for(i=0;i<=n;i++){
			for(j=0;j<=m;j++) {
				i&&(dp[i][j]=max(dp[i][j],max(dp[i-1][j],A[i]+B[j])));
				j&&(dp[i][j]=max(dp[i][j],max(dp[i][j-1],A[i]+B[j])));
			}
		}printf("%d\n",dp[n][m]);
	}
}

C
cqy大佬写的,没看。
D
你会发现那个\(5\)很诡异,比\(log\)小那么一点点。
我们考虑这样一个naive方法,进行\(n-1\)\((i,i+1)\),那么最后剩下\(n\)没法弄。
我们考虑在\((i,i+1)\)过程中保留一些\(i\)不操作用来消去\(n\)
如果你做过花神游历各国那道题你大概记着\(10^9\)开根号到\(1\)\(6\)次。
然后\(2\times 10^5\)就差不多是\(5\)次。
于是每次找到根号那个不弄然后做下去即可。
code:

#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define ll long long
#define db double
#define N 300000
#define M 200000
#define mod 998244353
#define eps (1e-7)
#define U unsigned int
#define IT set<ques>::iterator
#define Gc() getchar() 
#define Me(x,y) memset(x,y,sizeof(x))
using namespace std;
int n,m,T,A[N+5],fl[N+5],now,x[N+5],y[N+5],cnt,pus;
I void insert(int u,int v){x[++cnt]=u;y[cnt]=v;}
int main(){
	freopen("1.in","r",stdin);
	re int i,j;scanf("%d",&T);while(T--){
		scanf("%d",&n);for(i=1;i<=n;i++) A[i]=i,fl[i]=0;cnt=0;now=n;fl[n]=1;while(now>2)pus=ceil(sqrt(now)),fl[pus]=1,now=pus;
		for(i=1;i<=n;i++)!fl[i]&&(insert(i,i+1),0);now=n;while(A[now]>2){
			pus=ceil(sqrt(A[now])),insert(now,pus),insert(now,pus);now=pus;
		}
		printf("%d\n",cnt);for(i=1;i<=cnt;i++) printf("%d %d\n",x[i],y[i]); 
	}
}

E
cqy大佬写的,没看。
F
毛子真的不会数据结构(
首先我们考虑一根链挂上去肯定是中间一折两边一边一半。
然后挂链的顺序肯定是从大到小因为如果小的挂上去可能会出现最后大的没地方挂的处境。
最后挂链肯定是挂能挂的最上面。
然后每挂完一根链记录一下答案,最后取\(min\)即可。
这个东西用线段树很好维护。时间复杂度\(O(nlogn)\)
但是这道题有单调性可以\(O(n)\)
具体的排序用桶排。发现我们要找最浅的和第\(k\)浅的点,这些点都是单调的,用差分维护一下即可。
弄个指针维护一下就是\(O(n)\)的。
code(线段树的):

#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define ll long long
#define db double
#define N 400000
#define W 400000
#define mod 998244353
#define eps (1e-7)
#define U unsigned int
#define IT set<ques>::iterator
#define Gc() getchar() 
#define Me(x,y) memset(x,y,sizeof(x))
using namespace std;
int n,k,A[N+5],ans=1e9,now,pus;ll F[N+5<<2],sum[N+5<<2];
I void pushF(int l,int r,int x){F[x]+=F[x>>1];sum[x]+=F[x>>1]*(r-l+1);}
I void push(int l,int r,int x){if(!F[x]) return;int m=l+r>>1;pushF(l,m,x<<1);pushF(m+1,r,x<<1|1);F[x]=0;}
I void get(int x,int y,int z,int l=0,int r=W,int now=1){
	if(x<=l&&r<=y){F[now]+=z;sum[now]+=z*(r-l+1);return;}int m=l+r>>1;push(l,r,now);
	x<=m&&(get(x,y,z,l,m,now<<1),0);y>m&&(get(x,y,z,m+1,r,now<<1|1),0);sum[now]=sum[now<<1]+sum[now<<1|1];
}
I int find(int z,int l=0,int r=W,int now=1){
	if(l==r) return l;int m=l+r>>1;push(l,r,now);/*printf("%d %d %d %d\n",l,r,sum[now],z);*/return sum[now<<1]>=z?find(z,l,m,now<<1):find(z-sum[now<<1],m+1,r,now<<1|1);
}
int main(){
	freopen("1.in","r",stdin);
	re int i;scanf("%d%d",&n,&k);for(i=1;i<=n;i++) scanf("%d",&A[i]);sort(A+1,A+n+1);
	get(0,0,1);for(i=n;i;i--){
		now=find(1);get(now,now,-1);/*printf("%d\n",find(2));*/(A[i]>2)&&(get(now+2,now+1+(A[i]-1)/2,1),0);A[i]>1&&(get(now+2,now+1+A[i]/2,1),0);
		if(sum[1]>=k)now=find(k),ans=min(ans,now);//printf("%d\n",ans);
	}
	printf("%d\n",(ans==1e9)?-1:ans); 
}
posted @ 2021-07-06 22:07  275307894a  阅读(49)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end