2018.10.13 队测总结

2018.10.13队测总结

T3 克卜勒(kepler)<好题(毒瘤题)置顶>

T3

解题思路:

用两个树状数组维护,第一个树状数组按编号插入,维护小圈内各点是否通达(小圈内路径上的点编号相邻,如区间查询的值等于总点数则连通,另外要考虑反着走),第二个树状数组每个小圈开三个点分别记录小圈起始点,起始点和结束点是否连通,和结束点的信息,就可以用区间查询(原理同上)统计是否连通。修改时分别维护两个树状数组信息。

#pragma GCC optimize(2)
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define low(x) (x&(-x))
using namespace std;
typedef long long ll;
int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9') ch=='-'&&(f=-1),ch=getchar();
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x*f;
}
const int N=10010,M=5e5+10;
int n,tot,sum;bool val[M];
int *a[N],st[N],ed[N],siz[N],w[M],belong[M];
struct BIT
{
	int c[M<<1];
	void add(int x,int y,int k){for (;x<=k;x+=low(x)) c[x]+=y;}
	int query(int x){int su=0;while (x) su+=c[x],x-=low(x);return su;}
}bit[2];
bool get(int x,int y)
{
	if (x==y) return 1;
	if (x>y) swap(x,y);
	return (bit[0].query(y)-bit[0].query(x-1)==y-x+1)||
		(bit[0].query(x)-bit[0].query(a[belong[x]][1]-1)+bit[0].query(a[belong[y]][siz[belong[y]]])-bit[0].query(y-1)==siz[belong[y]]-(y-x-1));
}//判小圈两点是否相通
bool get1(int x,int y)
{
	if (x==y) return 1;
	if (x>y) swap(x,y);
	return (bit[1].query(y)-bit[1].query(x-1)==y-x+1)||(bit[1].query(x)+bit[1].query(3*n)-bit[1].query(y-1)==3*n-y+1+x);
}//判大圈两点是否相通
int main()
{
	n=read();a[0]=&w[0];
	for (int i=1;i<=n;++i)
	{
		siz[i]=read();
		a[i]=a[i-1]+siz[i-1];
		for (int j=1;j<=siz[i];++j)val[++sum]=read(),w[sum]=sum,belong[sum]=i;
		st[i]=read(),ed[i]=read();
	}
	for (int i=1;i<=n;++i)
		for (int j=1;j<=siz[i];++j)bit[0].add(a[i][j],val[a[i][j]],sum);
	for (int i=1,x;i<=n;++i)
	{
		x=i*3;bit[1].add(x-1,get(a[i][st[i]],a[i][ed[i]]),n*3);
		bit[1].add(x-2,val[a[i][st[i]]],n*3);
		bit[1].add(x , val[a[i][ed[i]]],n*3);
	}
	for (int i=0,_=read(),x,y,mode;i<_;++i)
	{
		mode=read();
		if (mode==1)
		{
			x=read();int u=belong[x];
			if (x==a[u][st[u]]) 
				bit[1].add(3*u-2,-val[x],n*3),bit[1].add(3*u-2,val[x]^1,n*3);
			else if (x==a[u][ed[u]]) 
				bit[1].add(3*u,-val[x],n*3),bit[1].add(3*u,val[x]^1,n*3);
			bit[1].add(u*3-1,-get(a[u][st[u]],a[u][ed[u]]),n*3);
			bit[0].add(x,-val[x],sum),bit[0].add(x,val[x]^1,sum);
			bit[1].add(u*3-1,get(a[u][st[u]],a[u][ed[u]]),n*3),val[x]^=1;
		}
		if (mode==2)
		{
			x=read(),y=read();
			int u=belong[x],v=belong[y];
			if
			(
				(get1(3*u,3*v-2)&&get(x,a[u][ed[u]])&&get(y,a[v][st[v]]))||
				(get1(3*v,3*u-2)&&get(x,a[u][st[u]])&&get(y,a[v][ed[v]]))
			)puts("Yes");//先从大圈判,再从小圈判,否则会被卡,见下图
			else if (u==v&&get(x,y)) puts("Yes");else puts("No");
		}
	}
	return 0;
}

下图黑点表示可以通行,白点反之,双边表示大圈边,单边表示小圈边,此时A点和B点仍可连通

T1 我要的幸福(happiness)

T1

解题思路:模拟(考场已A,无心写思路)

#include<cstdio>
#include<algorithm>
using namespace std;
int read()
{
	int x=0;char ch=getchar();
	while (ch<'0'||ch>'9') ch=getchar();
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x;
}
const int N=1010;
int n,m,top;
int a[N][N];bool bo[N][N];
int sta[N*2];
bool dfs(int x,int y)
{
	if (bo[x][y]||(!a[x][y])) return 0;
	if (x==n&&y==m) return sta[++top]=a[x][y],1;
	if (x==n)
	{
		if (dfs(x,y+1)) return sta[++top]=a[x][y],1;
		else return bo[x][y]=1,0;
	}
	if (y==m)
	{
		if (dfs(x+1,y)) return sta[++top]=a[x][y],1;
		else return bo[x][y]=1,0;
	}
	if (a[x+1][y]<a[x][y+1])
	{
		if (dfs(x+1,y)) return sta[++top]=a[x][y],1;
		else if (dfs(x,y+1)) return sta[++top]=a[x][y],1;
		else return bo[x][y]=1,0;
	}
	else 
	{
		if (dfs(x,y+1)) return sta[++top]=a[x][y],1;
		else if (dfs(x+1,y)) return sta[++top]=a[x][y],1;
		else return bo[x][y]=1,0;
	}
}
int main()
{
	n=read(),m=read();
	for (int i=1;i<=n;++i)
		for (int j=1;j<=m;++j)
			a[i][j]=read();
	if (!dfs(1,1)) puts("Oh,the life is too difficult!");
	else 
	{
		while (top>1) printf("%d ",sta[top]),--top;
		printf("%d\n",sta[1]);
	}
	return 0;
}

T2 天黑黑(dark)

T2

解题思路:模拟(考场已A,无心写思路)

#pragma GCC optimize(2)
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9') ch=='-'&&(f=-1),ch=getchar();
	while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
	return x*f;
}
const int N=4e5+10;
int a[N],top=1,tot;ll sum;
char s[N];
bool cmp(int x,int y){return x>y;}
int dfs(int i)
{
	if (s[i]=='X') return 1;
	else if (s[i]=='A') return dfs(++tot)+dfs(++tot);
	else return max(dfs(++tot),dfs(++tot));
}
int main()
{
	scanf("%s",s+1);
	while (~scanf("%d",&a[top]))++top;
	sort(a+1,a+top,cmp);
	int q=dfs(++tot);
	for (int i=1;i<=q;++i) sum+=a[i];
	printf("%lld\n",sum);
	return 0;
}
posted @ 2018-10-16 16:03  蒟蒻czx  阅读(176)  评论(0编辑  收藏  举报