SDOI2017 Round1 Day1 题解 (BZOJ4816 BZOJ4817 BZOJ4818)

不知道有几个AK的,除了出题人SB搬了个BZOJ3779以外,应该没什么因素阻碍AK吧。要是SCOI考这套题多好。

BZOJ4816 数字表格

SB反演,推出$ans=\prod_{i=1}^nf^{\sum_{j=1}^{\left\lfloor\frac ni\right\rfloor}\mu(j)\left\lfloor\frac n{ij}\right\rfloor\left\lfloor\frac m{ij}\right\rfloor}(i)$,直接$O(n^{\frac34}+n^{\frac12}logn)$计算。

#include<algorithm>
#include<cstdio>
using namespace std;
typedef unsigned long long ll;
const int p=1e9+7;
const int N=1e6+5;
ll wop(ll a,ll n){
	ll s=1;
	for(;n;n>>=1){
		if(n&1)s=s*a%p;
		a=a*a%p;
	}
	return s;
}
ll f[N],g[N];
int r[N];
bool vis[N];
ll sol(int n,int m){
	ll s=0;
	int i=1;
	while(i<=n){
		int j=min(n/(n/i),m/(m/i));
		s+=(g[j]-g[i-1])*(n/i)*(m/i);
		i=j+1;
	}
	return s;
}
int main(){
	f[1]=1;
	for(int i=2;i<N;++i)
		f[i]=(f[i-1]+f[i-2])%p;
	f[0]=1;
	for(int i=1;i<N;++i)
		(f[i]*=f[i-1])%=p;
	g[1]=1;
	int l=0;
	for(int i=2;i<N;++i){
		if(!vis[i])
			g[r[l++]=i]=-1;
		for(int*j=r;;++j){
			if(i**j>=N)break;
			vis[i**j]=1;
			if(i%*j==0)break;
			g[i**j]=-g[i];
		}
	}
	for(int i=2;i<N;++i)
		g[i]+=g[i-1];
	int t,n,m;
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&n,&m);
		if(n>m)swap(n,m);
		ll s=1;
		int i=1;
		while(i<=n){
			int j=min(n/(n/i),m/(m/i));
			(s*=wop(f[j]*wop(f[i-1],p-2)%p,sol(n/i,m/i)))%=p;
			i=j+1;
		}
		printf("%lld\n",s);
	}
}

BZOJ4817 树点涂色

做法同BZOJ3779。

#include<algorithm>
#include<cstdio>
#define I (J+1)
#define J (i+j>>1)
#define P (k<<1)
#define S (P^1)
using std::max;
const int N=1e5+5;
int n,dfn;
typedef int arr[N];
arr c1,c2,c3,c4,c5,f1,f2,g;
struct edge{
	int v;
	edge*s;
}e2[N*2];
edge*l=e2,*h[N];
void ins(int u,int v){
	edge s={v,h[u]};
	*(h[u]=l++)=s;
}
void dfs(int u){
	c1[g[f1[u]=++dfn]=u]=1;
	for(edge*i=h[u];i;i=i->s)
		if(i->v!=c2[u]){
			c3[i->v]=c3[c2[i->v]=u]+1;
			dfs(i->v);
			c1[u]+=c1[i->v];
			if(c1[i->v]>c1[c4[u]])
				c4[u]=i->v;
		}
	f2[u]=dfn;
}
int lca(int s,int t){
	while(c5[s]!=c5[t])
		c3[c5[s]]>c3[c5[t]]?s=c2[c5[s]]:t=c2[c5[t]];
	return c3[s]<c3[t]?s:t;
}
namespace seg{
	struct node{int d,s;}a[N*4];
	void upd(int k){
		a[k].s=max(a[P].s,a[S].s)+a[k].d;
	}
	void inc(int d,int s,int t,int i,int j,int k){
		if(s<=i&&j<=t)
			a[k].d+=d,a[k].s+=d;
		else{
			if(s<I)inc(d,s,t,i,J,P);
			if(t>J)inc(d,s,t,I,j,S);
			upd(k);
		}
	}
	int ask(int s,int t,int i,int j,int k){
		if(s==i&&j==t)return a[k].s;
		int r=t<I?ask(s,t,i,J,P):s>J?ask(s,t,I,j,S):max(ask(s,J,i,J,P),ask(I,t,I,j,S));
		return r+a[k].d;
	}
}
void inc(int s,int d){
	seg::inc(d,f1[s],f2[s],1,n,1);
}
struct node;
typedef node*ptr;
struct node{ptr i,j,p;}e[N];
bool root(ptr o){return o!=o->p->i&&o!=o->p->j;}
void turn(ptr o){
	ptr s=o->p,t=s->p;
	if(!root(s))(s==t->i?t->i:t->j)=o;
	o->p=t,s->p=o;
	if(o==s->i)
		s->i=o->j,o->j->p=s,o->j=s;
	else
		s->j=o->i,o->i->p=s,o->i=s;
}
ptr splay(ptr o){
	while(!root(o)){
		if(!root(o->p))turn(o==o->p->i^o->p==o->p->p->i?o:o->p);
		turn(o);
	}
	return o;
}
void inc(ptr&o,int d){
	if(o!=e){
		while(o->i!=e)o=o->i;
		inc(splay(o)-e,d);
	}
}
ptr exp(ptr o){
	ptr s=e;
	for(;o!=e;o=o->p){
		inc(s,-1);
		ptr t=splay(o)->j;
		o->j=s,s=o;
		inc(t,1);
	}
	return s;
}
int ask1(int u){
	return seg::ask(f1[u],f2[u],1,n,1);
}
int ask2(int u){
	return seg::ask(f1[u],f1[u],1,n,1);
}
int main(){
	int m,o,u,v;
	scanf("%d%d",&n,&m);
	for(int i=2;i<=n;++i)
		scanf("%d%d",&u,&v),ins(u,v),ins(v,u);
	dfs(1);
	for(int i=1;i<=n;++i){
		e[i]=(node){e,e,e+c2[i]};
		if(c4[c2[i]]!=i)
			for(int j=i;j;j=c4[j])c5[j]=i;
		inc(i,1);
	}
	while(m--){
		scanf("%d%d",&o,&u);
		if(o==1)exp(e+u);
		else if(o==2){
			scanf("%d",&v);
			printf("%d\n",ask2(u)+ask2(v)-ask2(lca(u,v))*2+1);
		}else
			printf("%d\n",ask1(u));
	}
}

BZOJ4818 序列计数

线性筛预处理贡献,矩阵快速幂优化DP。前者复杂度$O(m)$,后者复杂度$O(p^3logn)$。注意到矩阵是循环矩阵,所以可以优化到$O(p^2logn)$,用FFT可以进一步优化到$O(plogplogn)$。

代码是$O(m+p^2logn)$的。

#include<cstdio>
#include<cstring>
typedef unsigned long long ll;
const int p=20170408;
const int N=100;
const int M=2e7+5;
int n,m,l,q1[M/10],*q2=q1,c[N][2],e1[N],e2[N],f1[N],f2[N];
bool v[M];
inline void mul(int*a,int*b){
	static ll c[N];
	memset(c,0,sizeof c);
	for(int i=0;i<l;++i)
		for(int j=0;j<l;++j)
			c[(i+j)%l]+=(ll)a[i]*b[j];
	for(int i=0;i<l;++i)
		a[i]=c[i]%p;
}
int main(){
	scanf("%d%d%d",&n,&m,&l);
	for(int i=2;i<=m;++i){
		if(!v[i])*q2++=i;
		for(int*j=q1;j<q2;++j){
			if(i**j>m)break;
			v[i**j]=1;
		}
		++c[i%l][v[i]^1];
	}
	++c[1%l][0];
	for(int i=0;i<l;++i){
		f1[i]=c[i][0]+c[i][1];
		f2[i]=c[i][0];
	}
	e1[0]=e2[0]=1;
	for(;n;n>>=1){
		if(n&1)
			mul(e1,f1),mul(e2,f2);
		if(n>1)
			mul(f1,f1),mul(f2,f2);
	}
	int s=(e1[0]-e2[0]+p)%p;
	printf("%d\n",s);
}
时间: 2024-10-11 13:19:03

SDOI2017 Round1 Day1 题解 (BZOJ4816 BZOJ4817 BZOJ4818)的相关文章

SDOI2017 Round1 Day2 题解

T2好厉害啊--AK不了啦--不过要是SCOI考这套题就好了240保底. BZOJ4819 新生舞会 模板题,分数规划+二分图最大权匹配.费用流跑得过,可以不用KM. #include<bits/stdc++.h> #define pb push_back using namespace std; typedef double flo; const int inf=1e9; const int N=205; struct edge{ int v,c; flo w; }e[20400]; vec

NOI2014 Day1 题解。

自测100+100+62=262. BUAA给出的成绩是200,T3 checker评测windows选手答案都为RE. 起床困难综合征 sleep 题意:在[0,m]中取一个整数,使得n次给定的位运算操作后(包括and&,or|,xor^),答案最大.(m<=10^9,n<=10^5) 送分题.也许是NOI2013的金牌线偏低,DZD主席希望今年分数好看些. 二进制拆分. 先计算出每一位0/1经过n次位运算的答案. 再用数位DP求出答案最大值. 时间复杂度O(nlg^m). 1 #i

Noip 2016 Day1 题解

老师让我们刷历年真题, 然后漫不经心的说了一句:“你们就先做做noip2016 day1 吧” ...... 我还能说什么,,,,,老师你这是明摆着伤害我们啊2333333333 预计分数:100+25+24 实际分数:100+25+12 T1:玩具谜题 题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业. 有一天, 这些玩具小人把小南的眼镜藏了起来. 小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外.如下图: 这时singer告诉小南一个谜題: “眼镜藏在我左数第3个玩具小

noi2017 day1 题解

d1t1 用线段树维护区间是否全0/全1,叶子上压位维护对应位置的数位,加法首先对叶子加,如需进位则向右找到第一个不是全1的叶子+1,中间部分全1部分打上反转标记,减法同理. #include<cstdio> int _(){ int x=0,f=1,c=getchar(); while(c<48)c=='-'?f=-1:0,c=getchar(); while(c>47)x=x*10+c-48,c=getchar(); return x*f; } const int N=1100

十连测Day1 题解

A. 奥义商店 有一个商店,n个物品,每个物品有一个价格和一种颜色. 有m个操作,操作有两种,一种是修改一个位置的价格,另一种是购买,每次购买指定一个公差d和一个位置k,找到包含这个位置k公差为d的同色最长等差数列,买下所有物品.让你给这个位置染成t种颜色中的一种(你来指定),其他位置会随机染成t种颜色之一,并保证这n-1个物品中第j种颜色的恰好有c[j]个.求最小期望花费保留四位小数. 注意询问相互独立,询问不会买走物品. 1<=n,m<=10^5,∑t<=2*10^5. 首先我们考虑

【BZOJ 4515】【SDOI 2016 Round1 Day1 T3】游戏

考场上写了lct,可惜当时对标记永久化的理解并不是十分深刻,导致调一个错误的程序调了4h+,最后这道题爆0了QwQ 现在写了树链剖分,用标记永久化的线段树维护轻重链,对于$s\rightarrow lca$,$lca\rightarrow t$分开讨论,把$a×dist+b$这个式子打开,提出常数项,发现是一个一次函数(也不是严格的一次函数,只不过有单调性就可以做了).标记永久化线段树做一下,每个节点维护一个当前区间的最小值就可以统计答案了233 这次又手残把“+”打成“*”调了一上午TwT,肉

Bzoj 2705: [SDOI2012]Longge的问题 欧拉函数,数论

2705: [SDOI2012]Longge的问题 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1959  Solved: 1229[Submit][Status][Discuss] Description Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题.现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N). Input 一个整数,为N. Output 一个整数,为所求的答案. Sample Inp

[SDOI2016 Round1] 数字配对

COGS 2221. [SDOI2016 Round1] 数字配对 http://www.cogs.pro/cogs/problem/problem.php?pid=2221 ★★★   输入文件:menci_pair.in   输出文件:menci_pair.out   简单对比时间限制:1 s   内存限制:128 MB [题目描述] 有 n 种数字,第 i 种数字是 ai.有 bi 个,权值是 ci. 若两个数字 ai.aj 满足,ai 是 aj 的倍数,且 aiaj 是一个质数,那么这两

【BZOJ】【2705】【SDOI2012】Longge的问题

欧拉函数/狄利克雷卷积/积性函数 2705: [SDOI2012]Longge的问题 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1275  Solved: 820[Submit][Status][Discuss] Description Longge的数学成绩非常好,并且他非常乐于挑战高难度的数学问题.现在问题来了:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N). Input 一个整数,为N. Output 一个整数,为所