Loading

CSP 后多校八

A. 回文

签到题.

A_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS{
	#define int long long
	#define lf long double
	#define pb push_back
	#define mp make_pair
	#define lb lower_bound
	#define ub upper_bound
	#define lbt(x) ((x)&(-(x)))
	#define Fill(x,y) memset(x,y,sizeof(x))
	#define Copy(x,y) memcpy(x,y,sizeof(x))
	#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
	auto read=[](int w=0,bool cit=0,char ch=getchar())->int{
		for(;!isdigit(ch);ch=getchar()) cit=(ch=='-');
		for(;isdigit(ch);ch=getchar()) w=(w<<3)+(w<<1)+(ch^48);
		return cit?(-w):w;
	};
} using namespace BSS;

const int mod=993244853,N=505;

char ch[N][N];

int m,n,sum,len,ans;
int dp[2][N][N];
// (x,n+m-x+1-i)
auto inc=[](int &x,int y)->void{ x+=y,x-=(x>=mod)*mod; };
signed main(){
	File(palin);
	n=read(),m=read(),sum=n+m-1,len=(sum>>1)+(sum&1);
	for(int i=1;i<=n;i++) scanf("%s",ch[i]+1);
	if(ch[1][1]!=ch[n][m]) puts("0"),exit(0);
	dp[1][1][n]=1;
	for(int l=1;l<len;l++){
		int now=(l&1),nxt=now^1;
		for(int i=1,lmi=min(n,l);i<=lmi;i++){
			int j=l-i+1;
			for(int x=n,lmx=n+1-l;x>=lmx;x--){
				int y=n+m-x+1-l;
				if(ch[i+1][j]==ch[x-1][y]){
					inc(dp[nxt][i+1][x-1],dp[now][i][x]);
				}
				if(ch[i+1][j]==ch[x][y-1]){
					inc(dp[nxt][i+1][x],dp[now][i][x]);
				}
				if(ch[i][j+1]==ch[x-1][y]){
					inc(dp[nxt][i][x-1],dp[now][i][x]);
				}
				if(ch[i][j+1]==ch[x][y-1]){
					inc(dp[nxt][i][x],dp[now][i][x]);
				}
			}
		}
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++) dp[now][i][j]=0;
		}
	}
	if(sum&1){
		for(int i=1;i<=n;i++) inc(ans,dp[len&1][i][i]);
	}
	else{
		int now=len&1;
		for(int i=1;i<=n;i++){
			for(int x=i-1;x<=i+1;x++){
				int j=len-i+1,y=n+m-x+1-len;
				// if(dp[now][i][x] and abs(i-x)+abs(y-j)==1) cout<<i<<' '<<j<<' '<<x<<' '<<y<<endl;
				if(abs(i-x)+abs(y-j)==1) inc(ans,dp[now][i][x]);
			}
		}
	}
	printf("%lld\n",ans),exit(0);
}

B. 快速排序

大模拟,观察题目手玩一下样例好像就行.

B_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS{
	// #define int long long
	#define lf long double
	#define pb push_back
	#define mp make_pair
	#define lb lower_bound
	#define ub upper_bound
	#define lbt(x) ((x)&(-(x)))
	#define Fill(x,y) memset(x,y,sizeof(x))
	#define Copy(x,y) memcpy(x,y,sizeof(x))
	#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
	auto read=[](int w=0,bool cit=0,char ch=getchar())->int{
		for(;!isdigit(ch);ch=getchar()) cit=(ch=='-');
		for(;isdigit(ch);ch=getchar()) w=(w<<3)+(w<<1)+(ch^48);
		return cit?(-w):w;
	};
} using namespace BSS;

const int N=5e5+21;

char ch[N];
int m,n,cnt;
int val[N],tmp[N];
auto Work=[]()->void{
	n=read(),cnt=0; int flag=1;
	for(int i=0;i<=n+5;i++) val[i]=0;
	for(int i=1;i<=n;i++){
		scanf("%s",ch+1);
		if(ch[1]=='n'){ val[i]=-1,flag=0; continue; }
		for(int j=1,lmj=strlen(ch+1);j<=lmj;j++){
			val[i]=(val[i]<<3)+(val[i]<<1)+(ch[j]^48);
		}
		tmp[++cnt]=val[i];
	}
	sort(tmp+1,tmp+1+cnt); int lst=1,now=-1;
	for(int i=1;i<=n;i++){
		if(!(~val[i])) { printf("nan "); continue; }
		if(val[i]<now) continue;
		int nxt=lb(tmp+1,tmp+1+cnt,val[i])-tmp;
		for(int j=lst;j<=nxt;j++) printf("%d ",tmp[j]),now=tmp[j],tmp[j]=-1;
		lst=nxt+1;
	}
	puts("");
};
signed main(){
	File(qsort);
	for(int Ts=read();Ts;Ts--) Work();
}

C. 混乱邪恶

挺牛逼的一道题,没有被启发向正解的方向,但是有被启发到.

题目中给出几个信息:互不相同的几个数,范围在 \(1e6\) 以内,个数是 \(\dfrac{2m}{3}\) 以上.

可以发现,如果没啥经验的话,基本无从下手,这个时候能做的就只有大力猜测..

到了猜测结论这一步的时候就应该一次次地考虑很多方向地去猜、证明,不会证就应该大力手玩,或者直接码然后通过断言、大样例等自行验证.

首先会很自然地考虑到排序,然后考虑分组.

之后一个可能猜到的方向就是挪动组之间的数,然后消去差值.

证明的话,发现有至少 \(\frac{1}{3}\) 个数是相邻的( 即差值为 \(1\) ),于是就可以消去那些不是相邻的了.

C_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS{
	#define int long long 
	#define lf long double
	#define pb push_back
	#define mp make_pair
	#define lb lower_bound
	#define ub upper_bound
	#define lbt(x) ((x)&(-(x)))
	#define Fill(x,y) memset(x,y,sizeof(x))
	#define Copy(x,y) memcpy(x,y,sizeof(x))
	#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
	auto read=[](int w=0,bool cit=0,char ch=getchar())->int{
		for(;!isdigit(ch);ch=getchar()) cit=(ch=='-');
		for(;isdigit(ch);ch=getchar()) w=(w<<3)+(w<<1)+(ch^48);
		return cit?(-w):w;
	};
} using namespace BSS;

const int N=1e6+21;

int m,n,sum,cnt;
int a[N],o[N],ans[N];
struct I { int u,v,w; } p[N];
signed main(){
	File(chaoticevil);
	puts("NP-Hard solved");
	n=read(),m=read(),m=n;
	for(int i=1;i<=n;i++) a[i]=o[i]=read();
	if(m&1) a[++m]=0; sort(a+1,a+1+m);
	for(int i=2;i<=m;i+=2){
		p[++cnt].u=a[i],p[cnt].v=a[i-1],p[cnt].w=a[i]-a[i-1],sum+=p[cnt].w,ans[a[i]]=1;
	}
	sort(p+1,p+1+cnt,[](I i,I j){ return i.w>j.w; });
	for(int i=1;i<=cnt;i++){
		if(p[i].w*2>sum) continue;
		sum-=p[i].w*2,ans[p[i].u]^=1,ans[p[i].v]^=1;
	}
	assert(!sum);
	for(int i=1;i<=n;i++){
		printf("%d ",ans[o[i]] ? 1 : -1 );
	}
	exit(0);
}

D. 校门外歪脖树上的鸽子

牛逼数据结构.

一个牛逼的想法,就是自己的贡献可以存到兄弟节点上.

对于一些边界问题,比如自己没有兄弟给自己加贡献,那就凭空创造一个兄弟.

感觉数据结构对于问题的转化总是很 \(native\).

D_code
#include<bits/stdc++.h>
using namespace std;
namespace BSS{
	#define int long long 
	#define lf long double
	#define pb push_back
	#define mp make_pair
	#define lb lower_bound
	#define ub upper_bound
	#define lbt(x) ((x)&(-(x)))
	#define Fill(x,y) memset(x,y,sizeof(x))
	#define Copy(x,y) memcpy(x,y,sizeof(x))
	#define File(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
	auto read=[](int w=0,bool cit=0,char ch=getchar())->int{
		for(;!isdigit(ch);ch=getchar()) cit=(ch=='-');
		for(;isdigit(ch);ch=getchar()) w=(w<<3)+(w<<1)+(ch^48);
		return cit?(-w):w;
	};
} using namespace BSS;

const int N=2e6+21;

int m,n,rt,ops,cnt,bit;
int fa[N],le[N],ri[N],rk[N],tp[N],id[N];
int dfn[N],top[N],siz[N],dep[N];
int hson[N],lson[N],rson[N];
struct Seg_Tree{
	#define ls (x<<1)
	#define rs (x<<1|1)
	struct O { int w,sum,lzy; } tr[N<<2];
	inline void getval(int x,int w){ tr[x].lzy+=w,tr[x].w+=w*tr[x].sum; }
	inline void pushup(int x){ tr[x].w=tr[ls].w+tr[rs].w; }
	inline void spread(int x){
		int &lzy=tr[x].lzy; if(!lzy) return ;
		getval(ls,lzy),getval(rs,lzy),lzy=0;
	}
	inline void opd(int x,int l,int r,int px,int w){
		if(l==r) return tr[x].sum+=w,void();
		int mid=(l+r)>>1; 
		px<=mid ? opd(ls,l,mid,px,w) : opd(rs,mid+1,r,px,w) ;
		tr[x].sum=tr[ls].sum+tr[rs].sum;
	}
	inline void upd(int x,int l,int r,int ql,int qr,int w){
		if(ql>qr) return ;
		if(l>=ql and r<=qr) return getval(x,w),void();
		int mid=(l+r)>>1; spread(x);
		if(ql<=mid) upd(ls,l,mid,ql,qr,w);
		if(qr>mid) upd(rs,mid+1,r,ql,qr,w);
		pushup(x);
	}
	inline int qry(int x,int l,int r,int ql,int qr){
		if(l>=ql and r<=qr) return tr[x].w;
		int mid=(l+r)>>1,res=0; spread(x);
		if(ql<=mid) res+=qry(ls,l,mid,ql,qr);
		if(qr>mid) res+=qry(rs,mid+1,r,ql,qr);
		pushup(x); return res;
	}
	#undef ls 
	#undef rs
}A,B;
inline void sch(int u){
	dep[u]=dep[fa[u]]+1;
	if(!lson[u]) return siz[u]=1,void(); 
	int &x=lson[u],&y=rson[u];
	sch(x),siz[u]+=siz[x],sch(y),siz[u]+=siz[y];
	if(le[x]>le[y]) swap(x,y); 
	le[u]=le[x],ri[u]=ri[y];
	hson[u]=(siz[x]>siz[y] ? x : y);
}
inline void dfs(int u,int high){
	rk[dfn[u]=++cnt]=u,tp[u]=high;
	if(u==lson[fa[u]]) A.opd(1,1,m,dfn[u],siz[rson[fa[u]]]);
	if(u==rson[fa[u]]) B.opd(1,1,m,dfn[u],siz[lson[fa[u]]]);
	if(!hson[u]) return ; dfs(hson[u],high);
	dfn[lson[u]] ? dfs(rson[u],rson[u]) : dfs(lson[u],lson[u]);
}
auto update=[](int x,int y,int w)->void{
	x=id[x-1],y=id[y+1];
	while(tp[x]^tp[y]){
		if(dep[tp[x]]>dep[tp[y]]) A.upd(1,1,m,dfn[tp[x]],dfn[x],w),x=fa[tp[x]];
		else B.upd(1,1,m,dfn[tp[y]],dfn[y],w),y=fa[tp[y]];
	}
	int z=(dep[x]>dep[y] ? y : x);
	if(x^z) A.upd(1,1,m,dfn[z]+1,dfn[x],w);
	if(y^z) B.upd(1,1,m,dfn[z]+1,dfn[y],w);
	x=dfn[lson[z]],A.upd(1,1,m,x,x,-w);
	y=dfn[rson[z]],B.upd(1,1,m,y,y,-w);
};
auto query=[](int x,int y,int res=0)->int{
	x=id[x-1],y=id[y+1];
	while(tp[x]^tp[y]){
		if(dep[tp[x]]>dep[tp[y]]){
			res+=A.qry(1,1,m,dfn[tp[x]],dfn[x]),x=fa[tp[x]];
		} 
		else res+=B.qry(1,1,m,dfn[tp[y]],dfn[y]),y=fa[tp[y]];
	}
	int z=(dep[x]>dep[y] ? y : x);
	if(x^z) res+=A.qry(1,1,m,dfn[z]+1,dfn[x]);
	if(y^z) res+=B.qry(1,1,m,dfn[z]+1,dfn[y]);
	x=dfn[lson[z]],res-=A.qry(1,1,m,x,x);
	y=dfn[rson[z]],res-=B.qry(1,1,m,y,y);
	return res;
};
signed main(){
	File(pigeons);
	n=read(),ops=read(),m=n; int x,y;
	for(int i=1;i<=n;i++) le[i]=i,ri[i]=i,id[i]=i;
	for(int i=2;i<=n;i++){
		x=read(),y=read(),m++;
		fa[x]=m,fa[y]=m,lson[m]=x,rson[m]=y;
	}
	for(int i=1;i<=m;i++) if(!fa[i]) { rt=i; break; }
	fa[rt]=++m,rson[m]=rt,rt=m,lson[m]=m+1,fa[++m]=rt,id[0]=m;
	fa[rt]=++m,lson[m]=rt,rt=m,rson[m]=m+1,fa[++m]=rt,id[n+1]=m;
	sch(rt),dfs(rt,rt); int l,r,w;
	// for(int i=1;i<=m;i++) cout<<lson[i]<<' '<<rson[i]<<'\n'; puts("");
	while(ops--){
		if(read()&1) l=read(),r=read(),w=read(),update(l,r,w);
		else l=read(),r=read(),printf("%lld\n",query(l,r));
	}
	exit(0);
}
posted @ 2021-11-06 07:29  AaMuXiiiiii  阅读(43)  评论(0编辑  收藏  举报