加载中…

返回上一页

2022NOIP A层联测27

下发文件(密码为原 accoders 比赛密码)

天平

搜索.

一个简单的性质:只要选出的砝码的 gcd 和所有砝码的 gcd 相等,这个组合就是合法的.

就拿样例举例:

3
15 25 9

可以发现怎么组合都是只有 925 组合才能消掉 15.

直接爆搜,然后就有了 98 分的好成绩.

拿一个后缀和优化,如果选到当前这个数,再选后面的所有数都比要求的 gcd 大,直接返回.

点击查看代码
#include<bits/stdc++.h>
#define ll int
#define rg register
#define rll rg ll
#define pll pair<ll,ll>
#define maxn 3001
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
inline ll read()
{
	rg bool f=0;rll x=0;rg char ch=getchar();while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar(); return f?-x:x;
}
inline void write(rll x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10);putchar(x%10|'0'); }
ll n,a[maxn],g,hz[maxn],ans=0x7fffffff;
inline ll gcd(rll x,rll y) { if(!y) return x; return gcd(y,x%y); }
inline void dfs(rll x,rll num,rll gd)
{
	if(gd==g) { ans=min(ans,x);return; } if(x>=min(ans,9)||gd<g||num==n+1||gcd(gd,hz[num+1])>g) return;
	for(rll i=num+1;i<=n;i++) { dfs(x+1,i,gcd(gd,a[i])); }
}
int main()
{
	freopen("weights.in","r",stdin); freopen("weights.out","w",stdout);
	// for(rll i=25;;i+=25) if(!((15+i)%9)) {cout<<i/25<<' '<<(15+i)/9<<endl;break;}
	n=read(); for(rll i=1;i<=n;i++) a[i]=read(); random_shuffle(a+1,a+n+1); if(a[1]==1) { putchar('1'); return 0; }
	g=a[1]; for(rll i=2;i<=n;i++) g=gcd(g,a[i]);
	hz[n]=a[n]; for(rll i=n-1;i;i--) hz[i]=gcd(hz[i+1],a[i]);
	for(rll i=1;i<=n;i++) dfs(1,i,a[i]); write(ans);
	return 0;
}

支配数据

一看区间修改查询肯定是线段树. 但是总的大小是 1e9,硬上肯定是不行地.

发现修改的区间最多只有 1e6 个,可以把修改离散化一下,将修改和查询的点进行处理. 存一下这些区间的端点,然后排序一下. 把每两个端点生成的区间当成一个节点放到线段树里.

但是这样不对. 如果有修改的区间重叠,这样会算重. 所以可以把有效的那些点单独作为一个区间,中间夹着的部分作为一个区间.

在预处理每个区间的权值的时候,直接暴力显然会 TLE,所以用一个 ST 表查就可以了.

这样并不需要动态开点,只用一棵查最小值的线段树就可以了.

点击查看代码
#include<bits/stdc++.h>
#define ll int
#define rg register
#define rll rg ll
#define pll pair<ll,ll>
#define maxn 400001
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
inline ll read()
{
	rg bool f=0;rll x=0;rg char ch=getchar();while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar(); return f?-x:x;
}
inline void write(rll x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10);putchar(x%10|'0'); }
struct node { ll op,l,r,x; }a[maxn];
ll n,k,m,q,mn=0x7fffffff,b[maxn],id[maxn<<2],len,id1[maxn<<2],len1,ans[maxn],posl[maxn],posr[maxn],cnt;
class st
{
private:
	ll mn[maxn][21];
public:
	inline void init(rll n)
	{
		for(rll i=1;i<=n;i++) mn[i][0]=b[i];
		for(rll j=1;j<=20;j++) for(rll i=1;i+(1<<j)-1<=n;i++) mn[i][j]=min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]);
	}
	inline ll query(rll l,rll r) { rll k=log2(r-l+1); return min(mn[l][k],mn[r-(1<<k)+1][k]); }
}s;
struct tree
{
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
	ll v,tag;
}t[maxn<<4];
#define pushup(rt) t[rt].v=min(t[ls(rt)].v,t[rs(rt)].v)
inline void pushdown(rll rt)
{
	if(t[rt].tag) t[ls(rt)].v=t[rt].tag,t[rs(rt)].v=t[rt].tag,
		t[ls(rt)].tag=t[rt].tag,t[rs(rt)].tag=t[rt].tag,t[rt].tag=0;
}
inline ll getmn(rll x)
{
	rll l=posl[x],r=posr[x],ans=0x7fffffff; if(r-l+1>=n) return mn; l=(l-1)%n+1,r=(r-1)%n+1;
	if(l>r) return min(s.query(1,r),s.query(l,n)); return s.query(l,r);
}
inline void build(rll rt,rll l,rll r)
{
	if(l==r) { t[rt].v=getmn(l); /*cout<<posl[l]<<' '<<posr[l]<<' '<<t[rt].v<<endl;*/ return; } rll mid=(l+r)>>1;
	build(ls(rt),l,mid); build(rs(rt),mid+1,r); pushup(rt);
}
inline void upd(rll rt,rll l,rll r,rll x,rll y,rll v)
{
	if(x<=l&&r<=y) { t[rt].v=t[rt].tag=v;return; } pushdown(rt); rll mid=(l+r)>>1;
	if(x<=mid) upd(ls(rt),l,mid,x,y,v); if(y>mid) upd(rs(rt),mid+1,r,x,y,v); pushup(rt);
}
inline ll query(rll rt,rll l,rll r,rll x,rll y)
{
	if(x<=l&&r<=y) return t[rt].v; pushdown(rt); rll mid=(l+r)>>1,ans=0x7fffffff;
	if(x<=mid) ans=query(ls(rt),l,mid,x,y); if(y>mid) ans=min(ans,query(rs(rt),mid+1,r,x,y)); return ans;
}
int main()
{
	freopen("data.in","r",stdin); freopen("data.out","w",stdout);
	// freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);
	n=read();k=read();m=n*k; for(rll i=1;i<=n;i++) mn=min(mn,b[i]=read()); q=read(); fprintf(stderr,"%lld %lld %lld\n",n,k,m);
	s.init(n);
	for(rll i=1;i<=q;i++) switch(a[i].op=read())
	{
	case 1:id[++len]=a[i].l=read(); id[++len]=a[i].r=read(); a[i].x=read(); break;
	case 2:id[++len]=a[i].l=read(); id[++len]=a[i].r=read(); break;
	}
	id[++len]=1,id[++len]=m; sort(id+1,id+len+1); len=unique(id+1,id+len+1)-id-1;// cout<<len<<endl;
	// sort(id2+1,id2+len2+1); len2=unique(id2+1,id2+len2+1)-id2-1;
	// for(rll i=1;i<=len2;i++) id[++len]=id2[i]; sort(id+1,id+len+1);// cout<<len<<endl;
	for(rll i=1;i<len;i++) { posl[++cnt]=id[i];posr[cnt]=id[i]; if(id[i+1]-id[i]>1) posl[++cnt]=id[i]+1,posr[cnt]=id[i+1]-1; }
	posl[++cnt]=id[len];posr[cnt]=id[len];
	fprintf(stderr,"%d\n",cnt);
	for(rll i=1;i<=q;i++) a[i].l=lower_bound(posl+1,posl+cnt+1,a[i].l)-posl,a[i].r=lower_bound(posr+1,posr+cnt+1,a[i].r)-posr;
	build(1,1,cnt); for(rll i=1;i<=q;i++) switch(a[i].op)
	{
	case 1:upd(1,1,cnt,a[i].l,a[i].r,a[i].x);break;
	case 2:write(query(1,1,cnt,a[i].l,a[i].r));putn;break;
	}
	return 0;
}

信息学的尽头

基环树模板题,没啥好说的.

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define rll rg ll
#define pll pair<ll,ll>
#define maxn 200001
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
inline ll read()
{
	rg bool f=0;rll x=0;rg char ch=getchar();while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar(); return f?-x:x;
}
inline void write(rll x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10);putchar(x%10|'0'); }
ll n,cnt,t,s,ans[maxn],a[maxn<<2],b[maxn<<2],st,len,sz[maxn],tot[maxn],sum[maxn<<1];
vector<pll> g[maxn];
bool fl[maxn];
inline bool dfs1(rll x,rll fa)
{
	fl[x]=1; for(rll i=0;i<g[x].size();i++)
	{
		rll to=g[x][i].first; if(to==fa) continue;
		if(fl[to]) { st=to; a[++cnt]=x; b[cnt]=g[x][i].second; len+=g[x][i].second; return 1; }
		if(dfs1(to,x)){ a[++cnt]=x; b[cnt]=g[x][i].second; len+=g[x][i].second; return x^st; }
	}
	return fl[x]=0;
}
inline void dfs2(rll x,rll fa)
{
	for(rll i=0;i<g[x].size();i++)
	{
		rll to=g[x][i].first; if(to==fa||fl[to]) continue;
		dfs2(to,x); tot[x]+=tot[to]+sz[to]*g[x][i].second; sz[x]+=sz[to];
	}
	sz[x]++;
}
inline void dfs3(rll x,rll fa)
{
	for(rll i=0;i<g[x].size();i++)
	{
		rll to=g[x][i].first; if(to==fa||fl[to]) continue;
		ans[to]=ans[x]+(n-sz[to])*g[x][i].second-sz[to]*g[x][i].second; dfs3(to,x);
	}
}
int main()
{
	freopen("end.in","r",stdin); freopen("end.out","w",stdout);
	n=read(); for(rll i=1,u,v,w;i<=n;i++) u=read(),v=read(),w=read(),g[u].push_back((pll) { v,w }),g[v].push_back((pll) { u,w });
	dfs1(1,0); for(rll i=1;i<=cnt<<1;i++) a[i+cnt]=a[i],b[i+cnt]=b[i]; for(rll i=1;i<=cnt<<1;i++) sum[i]=sum[i-1]+b[i];
	for(rll i=1;i<=cnt;i++) fl[a[i]]=1; for(rll i=1;i<=cnt;i++) dfs2(a[i],0);
	for(rll i=2;i<=cnt+1;i++) t+=tot[a[i]]+min(len-(sum[cnt+1]-sum[i]),sum[cnt+1]-sum[i])*sz[a[i]];
	for(rll i=2;i<=cnt+1;i++) if(sum[cnt+1]-sum[i]<=len-(sum[cnt+1]-sum[i])) { st=i;break; } for(rll i=st;i<=cnt+1;i++) s+=sz[a[i]];
	for(rll i=cnt+1;i<=cnt<<1;i++)
	{
		if(i^cnt+1)
		{
			t+=s*b[i]; t-=(n-s)*b[i]; s+=sz[a[i]];
			while(sum[i]-sum[st]>=len-(sum[i]-sum[st])) 
				s-=sz[a[st]],t+=((len-(sum[i]-sum[st]))-(sum[i]-sum[st]))*sz[a[st]],st++;
		}
		ans[a[i]]=t;
	}
	for(rll i=1;i<=cnt;i++) dfs3(a[i],0); for(rll i=1;i<=n;i++) write(ans[i]),put_;
	return 0;
}

球对称薛定谔方程

题目来自:

dp[i][j][k] 表示当前长度为 i、当前位置放 j、后面还有 k 个位置没有决定放的方案数.

转移:

  1. dp[i][j][k - 1] += dp[i][j][k],不再往当前位置放 j,后面决定放的位置减一;

  2. dp[i][j + 1][i] += dp[i][j][k],没有可以放的位置了,决定放的位置减小到 i

  3. dp[i + 1][j][k] += dp[i][j][k] × (k + 1):在当前位置放一个 jk 不变是因为 j 的后面还可以再放.

初始状态 dp[1][i][0] = 1 (i ∈ [1 , k])
答案即为 dp[n][k][0].

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define rll rg ll
#define pll pair<ll,ll>
#define maxn 302
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
inline ll read()
{
	rg bool f=0;rll x=0;rg char ch=getchar();while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar(); return f?-x:x;
}
inline void write(rll x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10);putchar(x%10|'0'); }
ll n,k,m,ans,dp[maxn][maxn][maxn];
int main()
{
	freopen("seq.in","r",stdin); freopen("seq.out","w",stdout);
	n=read();k=read();m=read(); for(rll i=1;i<=k;i++) dp[1][i][0]=1;
	for(rll i=1;i<=n;i++) for(rll j=1;j<=k;j++)
	{
		for(rll k=i;~k;k--) { if(k) (dp[i][j][k-1]+=dp[i][j][k])%=m; (dp[i+1][j][k]+=(k+1)*dp[i][j][k])%=m; }
		(dp[i][j+1][i]+=dp[i][j][0])%=m;
	}
	write(dp[n][k][0]);
	return 0;
}
posted @ 2022-11-13 19:33  1Liu  阅读(59)  评论(1)    收藏  举报