codeforces 794 (#414 DIV1+DIV2)

A Bank Robbery[1/1]

B Cutting Carrot[1/1]

C Naming Company[1/3]

博弈····其实挺有趣,得想到如果我的最小的要比他的最大的要优就放在前面否则就放在后面

#include <bits/stdc++.h>
using namespace std;
char a[300010],b[300010];
int ans[300010];
int main(int argc, char const *argv[])
{
	scanf("%s%s",a+1,b+1);
	int n=strlen(a+1);
	sort(a+1,a+1+n);sort(b+1,b+1+n,greater<char>());
	int l=1,r=n,al=1,ar=(n+1)/2,bl=1,br=n/2;
	while(l<=r)
	{
		if(a[al]<b[bl])ans[l++]=a[al++];
		else ans[r--]=a[ar--];if(l>r)break;
		if(a[al]<b[bl])ans[l++]=b[bl++];
		else ans[r--]=b[br--];
	}
	for(int i=1;i<=n;i++)printf("%c",ans[i]);
}

D Labelling Cities[0/1]

还没A,待补

E Choosing Carrot[1/2]

博弈结论,推导很有意思,虽然一开始有一点这样的想法···但是并没有想出来··qwq我没有智商···看了题解才会写···记录一下写法拓展一下思路····

划归一下博弈,假设剩下某个特定数字为赢剩下都为输这样看来最后的结果一定会是

$if (n为偶数 ) ans = max(a_{\frac{n}{2}},a_{\frac{n+1}{2}}) $

\(else\quad ans = min(a_{\frac{n+1}{2}},max(a_{\frac{n-1}{2}},a_{\frac{n+3}{2}}))\)

#include <bits/stdc++.h>
using namespace std;
int ans[3000010];
int l[3000010][2],a[3000010];
int mx=0;
int main(int argc, char const *argv[])
{
	int n;scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]),mx=max(mx,a[i]);
	if(n == 1){printf("%d\n",a[1] );return 0;}
	for(int i=1;i<n;i++)
      	l[i][0]=max(a[i],a[i+1]),
  		l[i][1] = min(a[i+1],max(a[i],a[i+2]));
  		l[n][1]=a[n];
  		l[0][1]=a[1];
	for(int i=0;i<=n;i++)ans[i]=max(l[(n+i)/2][(n-i)%2],l[(n-i)/2][(n-i)%2]);
	printf("%d %d ",ans[0],ans[1] );
	for(int i=2;i<n-1;i++)
      	ans[i]=max(ans[i],ans[i-2]),printf("%d ",ans[i]);
	printf("%d\n",mx );
	return 0;
}

F Leha and security system[1/14]

很有趣的线段树的问题 (你还是不懂线段树)

WA成sb···OAO太菜了qwq····

首先得清楚 \(T[now]. nxt[i]\) 所有的含义与性质···当前区间的 \(i\) 需要转变为 \(T[now]. nxt[i]\)

而向下传的时候需要更新下面的\(T[now<<1].nxt[i]\)(以\(now<<1\) 为例)

比如说 \(now\) 部分为 \(j->k\) 下方为 \(i -> j\) 更新后变成\(i->j->k\) 所以需要\(i->k\)

\(T[now<<1].nxt[i] = T[now].nxt[T[now<<1].nxt[i]]\) (一定要临时存一下QAQ)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[200010];
struct segment
{
	int l,r;
	ll sum[11];
	int nxt[11];
}T[100010<<3];
void pushup(int now)
{
	for(int i=0;i<10;i++)T[now].sum[i]=T[now<<1].sum[i]+T[now<<1|1].sum[i];
}
void build(int now,int l,int r)
{
	T[now].l = l,T[now].r = r;
	for(int i=0;i<=9;i++)T[now].nxt[i] = i;
	if(l == r){
		ll x = a[l],tot = 1ll,s;
		while(x)
		{
			s = x%10;
			T[now].sum[s]+=tot;
			tot*=10;x/=10;
		}
		return;
	}
	int m=(l+r)>>1;
	build(now<<1,l,m);build(now<<1|1,m+1,r);
	pushup(now);
}
int nxt1[11],nxt2[11];
void pushdown(int now)
{
	int l = T[now].l,r = T[now].r;
	if(r - l>=1){
		for(int i=0;i<=9;i++){
			nxt1[i] = T[now].nxt[T[now<<1].nxt[i]];
			nxt2[i] = T[now].nxt[T[now<<1|1].nxt[i]];
		}
		for(int i=0;i<=9;i++)T[now<<1].nxt[i] = nxt1[i];
		for(int i=0;i<=9;i++)T[now<<1|1].nxt[i] = nxt2[i];
	}
	ll tmp[11]={0};
	for(int i=0;i<=9;i++)tmp[T[now].nxt[i]]+=T[now].sum[i];
	for(int i=0;i<=9;i++)T[now].sum[i]=tmp[i],T[now].nxt[i]=i;
}
void modify(int now,int L,int R,int x,int y)
{
	int l = T[now].l,r=T[now].r;
	if(l>=L&&r<=R)
	{
		T[now].nxt[x]=y;pushdown(now);return;
	}
	int m = (l+r)>>1;
	pushdown(now<<1);pushdown(now<<1|1);
	if(L<=m)modify(now<<1,L,R,x,y);
	if(R>m)modify(now<<1|1,L,R,x,y);
	pushup(now);

}
ll query(int now,int L,int R)
{
	int l = T[now].l,r=T[now].r;
	ll sum=0;
	if(l>=L&&r<=R){
		for(int i=0;i<=9;i++)sum+=T[now].sum[i]*i;
		return sum;
	}
	int m = (l+r)>>1;
	pushdown(now<<1);pushdown(now<<1|1);
	if(L<=m)sum+=query(now<<1,L,R);
	if(R>m)sum+=query(now<<1|1,L,R);
	return sum;
}
int main()
{
	int n,q;scanf("%d%d",&n,&q);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	build(1,1,n);
	int l,r,x,y,s;
	while(q--)
	{
		scanf("%d",&s);
		if(s == 1)
		{
			scanf("%d%d%d%d",&l,&r,&x,&y);if(x == y)continue;
			modify(1,l,r,x,y);
		}
		else 
		{
			scanf("%d%d",&l,&r);
			printf("%lld\n", query(1,l,r));
		}
	}
	return 0;
}

G Replace All

待补··

posted @ 2018-04-10 17:02  miamiao  阅读(168)  评论(0编辑  收藏  举报