关于猫树

[BZOJ3636]教义问答手册

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n,L,q;
int a[100005],sum[100005],cnt[400005];
int dp[21][55][100005],loc[100005];
void build(int l=1,int r=n,int i=1,int dep=0){
	cnt[i]=dep;
	if(l==r){
		loc[l]=i;return ;
	}
	int mid=(l+r)>>1;
	for(int d=0;d<=L;d++){
		if(mid+d>r)break;
		dp[dep][d][mid+d]=sum[mid+d]-sum[mid];
		for(int i=mid+d+1;i<=r;i++)dp[dep][d][i]=max(i-1>mid?dp[dep][d][i-1]:0,i-L>mid?dp[dep][d][i-L]+sum[i]-sum[i-L]:(int)-1e9);
	}
	for(int d=0;d<=L;d++){
		if(mid-d+1<l)break;
		dp[dep][d][mid-d+1]=sum[mid]-sum[mid-d];
		for(int i=mid-d;i>=l;i--)dp[dep][d][i]=max(i+1<=mid?dp[dep][d][i+1]:0,i+L<=mid?dp[dep][d][i+L]+sum[i+L-1]-sum[i-1]:(int)-1e9);
	}
	build(l,mid,i<<1,dep+1);build(mid+1,r,i<<1|1,dep+1);
}
inline int lca(int x,int y){
	while(x!=y){
		if(cnt[x]>cnt[y])x>>=1;
		else y>>=1;
	}return cnt[x];
}
inline int query(int l,int r){
	int lc=lca(loc[l],loc[r]);
	int res=max(0,max(dp[lc][0][l]+dp[lc][0][r],dp[lc][L][l]+dp[lc][L][r]));
	for(int i=0;i<=L;i++)res=max(res,dp[lc][i][l]+dp[lc][L-i][r]);
	return res;
}
char cb[1<<18],*cs,*ct;
#define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<18,stdin),cs==ct)?0:*cs++)
inline void rd(int &x) {
	x = 0; char ch; int flg=1; while(!isdigit(ch=getc()))if(ch=='-')flg=-flg;
	do x=x*10+ch-'0'; while(isdigit(ch=getc())); x *= flg;
}
int main(){
	rd(n);rd(L);
	for(int i=1;i<=n;i++)rd(a[i]);
	for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
	for(int i=0;i<=20;i++){
		for(int d=0;d<=L;d++){
			for(int j=1;j<=n;j++)dp[i][d][j]=-1e9;
		}
	}
	build();
	scanf("%d",&q);
	while(q--){
		int l,r;rd(l);rd(r);
		printf("%d\n",query(l,r));
	}

	return 0;
}

CF1100F Ivan and Burgers

点击查看代码
#include <bits/stdc++.h>
using namespace std;
int rd(){int f=1,sum=0; char ch=getchar();while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}while(isdigit(ch)) {sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}return sum*f;}
struct ques{
	int l,r;
}q[500005];
int a[500005],p[500005],ans[500005],n,m;
struct node {
	int d[22];
	void clr() {
		memset(d,0,sizeof(d));
	}
	void ins(int x) {
		for(int i=20;i>=0;i--){
			if((x>>i)&1){
				if(d[i])x^=d[i];
				else {d[i]=x;break;}
			}
		}
	}
	int qry(){
		int res=0;
		for(int i=20;i>=0;i--)if((res^d[i])>res)res^=d[i];
		return res;
	}
}g[500005];
int merge(node x,node y){
	for(int i=20;i>=0;i--)x.ins(y.d[i]);
	return x.qry();
}
int tmp[500005];
void solve(int l,int r,int L,int R) {
	if(L>R) return;
	int mid=(l+r)>>1,t1=L-1,t2=0;
	g[mid].clr(); g[mid].ins(a[mid]);
	for(int i=mid+1;i<=r;i++)(g[i]=g[i-1]).ins(a[i]);
	for(int i=mid-1;i>=l;i--)(g[i]=g[i+1]).ins(a[i]);
	for(int i=L,x;i<=R;i++){
		x=p[i];
		if(q[x].r<=mid)p[++t1]=x;
		else if(q[x].l>mid) tmp[++t2]=x;
		else ans[x]=merge(g[q[x].l],g[q[x].r]);
	}
	for(int i=1;i<=t2;i++)p[t1+i]=tmp[i];
	solve(l,mid,L,t1); solve(mid+1,r,t1+1,t1+t2);
}
int main() {
	n=rd();
	for(int i=1;i<=n;i++) a[i]=rd();
	m=rd();
	int tot=0;
	for(int i=1;i<=m;i++) {
		q[i]=ques{rd(),rd()};
		if(q[i].l==q[i].r) ans[i]=a[q[i].l];
		else p[++tot]=i;
	}
	solve(1,n,1,tot);
	for(int i=1;i<=m;i++) printf("%d\n",ans[i]);
	return 0;
}

CF232E Quick Tortoise

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n,m,q;
char mp[505][505];
bitset<505> B[11][505][505];
int cnt[2005],id[505];
void build(int l=1,int r=n,int i=1,int dep=0){
	cnt[i]=dep;
	int mid=(l+r)>>1;
	for(int i=1;i<=m;i++){
		if(mp[mid][i]=='#')continue;
		B[dep][mid][i]=B[dep][mid][i-1];
		B[dep][mid][i][i]=1;
	}
	for(int i=mid+1;i<=r;i++){
		for(int j=1;j<=m;j++){
			if(mp[i][j]=='#')continue;
			B[dep][i][j]=(B[dep][i-1][j]|B[dep][i][j-1]);
		}
	}
	for(int i=m;i>=1;i--){
		B[dep][mid][i].reset();
		if(mp[mid][i]=='#')continue;
		B[dep][mid][i]=B[dep][mid][i+1];
		B[dep][mid][i][i]=1;
	}
	for(int i=mid-1;i>=l;i--){
		for(int j=m;j>=1;j--){
			if(mp[i][j]=='#')continue;
			B[dep][i][j]=(B[dep][i+1][j]|B[dep][i][j+1]);
		}
	}
	if(l==r){
		id[l]=i;
		return ;
	}build(l,mid,i<<1,dep+1);build(mid+1,r,i<<1|1,dep+1);
}
inline bool query(int a,int b,int c,int d){
	int x=id[a],y=id[c];
	while(x!=y){
		if(cnt[x]>cnt[y])x>>=1;
		else y>>=1;
	}
	return (B[cnt[x]][a][b]&B[cnt[y]][c][d]).count();
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%s",mp[i]+1);
	build();
	scanf("%d",&q);
	while(q--){
		int a,b,c,d;
		scanf("%d%d%d%d",&a,&b,&c,&d);
		puts(query(a,b,c,d)?"Yes":"No");
	}

	return 0;
}


[AGC028F] Reachable Cells

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n;
char mp[505][505];
long long sum[505][505],val[505][505];
int le[2][505][505],ri[2][505][505];
long long ans;
void dfs(int x,int y){
	if(val[x-1][y]||val[x][y-1]||!val[x][y])return ;
	val[x][y]=0;
	for(int i=y;i<=n;i++)sum[x][i]=sum[x][i-1]+val[x][i];
	dfs(x+1,y);dfs(x,y+1);
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%s",mp[i]+1);
		for(int j=1;j<=n;j++){
			if(mp[i][j]!='#')val[i][j]=mp[i][j]-'0';
			sum[i][j]=sum[i][j-1]+val[i][j];
		}
	}
	for(int i=n+1;i;i--){
		swap(le[0],le[1]);
		swap(ri[0],ri[1]);
		for(int j=n+1;j>=0;j--){
			if(!val[i][j]){
				for(int t=i;t<=n;t++)le[0][j][t]=n+1,ri[0][j][t]=0;
				continue;
			}
			le[0][j][i]=j;ri[0][j][i]=max(j,ri[0][j+1][i]);
			ans-=val[i][j]*val[i][j];
			for(int t=i+1;t<=n;t++)le[0][j][t]=min(le[1][j][t],le[0][j+1][t]);
			for(int t=i+1;t<=n;t++)ri[0][j][t]=max(ri[1][j][t],ri[0][j+1][t]);
			for(int t=i;t<=n;t++){
				if(le[0][j][t]<=ri[0][j][t])ans+=val[i][j]*(sum[t][ri[0][j][t]]-sum[t][le[0][j][t]-1]);
			}dfs(i,j);
		}
	}
	printf("%lld",ans);

	return 0;
}

posted @ 2022-01-15 14:39  一粒夸克  阅读(78)  评论(0编辑  收藏  举报