NOIP模拟72
T1 出了个大阴间题
解题思路
看了看数据,大概是个状压 DP,但是感觉记忆化搜索比较好写一点(然而并不是这样递归比迭代常熟大了许多。。)
不难判断出来 b 的数值与合并的顺序无关于是我们可以预先处理来,最大值也是可以直接求的,从大到小合并。
DP 记录一下已经选择的数字的状态,当前的 a 的方案数,总和以及是否可以达到最大值。
然后转移计算贡献就好了(真没啥好说的)
code
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
const int N=25,mod=1e9+7;
int n,m,cnt,b[N],s[N];
ll ans,maxn,lsh[N*N];
struct Node{int dat,all;bool can;}f[150][1ll<<18];
int Pre_work()
{
	sort(s+1,s+n+1);
	int a=s[1];
	for(int i=2;i<=n;i++)
		a=(a==s[i])?a+1:max(a,s[i]);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			lsh[++cnt]=s[i]+j-1;
	sort(lsh+1,lsh+cnt+1); cnt=unique(lsh+1,lsh+cnt+1)-lsh-1;
	return a;
}
void clear()
{
	for(int i=1;i<=cnt;i++)
		for(int j=0;j<(1<<n);j++)
			f[i][j].dat=-1;
}
Node dfs(int x,int sta,int a)
{
	int pos=lower_bound(lsh+1,lsh+cnt+1,a)-lsh;
	if(~f[pos][sta].dat) return f[pos][sta];
	if(x==n) return f[pos][sta]=(Node){0,1,a==maxn};
	int res=0,tot=0; bool can=false;
	for(int i=1;i<=n;i++)
	{
		if((sta>>i-1)&1) continue;
		int na=(a==s[i])?a+1:max(a,s[i]);
		int p=lower_bound(lsh+1,lsh+cnt+1,na)-lsh;
		Node temp=dfs(x+1,sta|(1ll<<i-1),na);
		if(!temp.can) continue; can=true;
		tot=(1ll*tot+temp.all)%mod;
		res=(res+1ll*(1ll*m*na%mod+b[x-1])*temp.all+temp.dat)%mod;
	}
	return f[pos][sta]=(Node){res,tot,can};
}
signed main()
{
	freopen("repair.in","r",stdin); freopen("repair.out","w",stdout);
	n=read(); m=read();
	for(int i=1;i<=n;i++) s[i]=read(),b[i]=b[i-1]*2+1;
	maxn=Pre_work();
	for(int i=1;i<=n;i++)
	{
		clear();
		Node temp=dfs(1,1ll<<i-1,s[i]);
		if(temp.can) ans=(ans+temp.dat)%mod;
	}
	printf("%lld %lld",maxn,ans);
	return 0;
}
T2 最简单辣快来做
解题思路
发现 n 的范围比较小,我们可以对于每个卫星的坐标离散化一下,维护四个方向(区域)的和。
然后计算询问的时候分别查询在所有卫星中距离最近的两个横坐标两个纵坐标。
对于四个区域的答案分别将剩余的在离散化数组间隙中的计算进去。
光速幂可以快速的求出 a 或者 b 的次方,省掉一个 log
code
#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
const int N=4e3+10,M=1e5+10,base=1e5;
int n,q,mod,w,h,a,b,pre[N][N][4];//0->left,up; 1->right,up; 2->left,down; 3->right,down
int cnt1,cnt2,val[N][N],lsh1[N<<1],lsh2[N<<1],pa1[M],pa2[M],pb1[M],pb2[M];
struct Node{int h,x,y;}s[N];
int power(int x,int y,int p=mod)
{
	if(y<0) return 0;
	if(x==a) return pa1[y/base]*pa2[y%base]%mod;
	return pb1[y/base]*pb2[y%base]%mod;
}
int solve()
{
	int x,y,ans=0; x=read(); y=read();
	int posx=upper_bound(lsh1+1,lsh1+cnt1+1,x)-lsh1-1;
	int posy=upper_bound(lsh2+1,lsh2+cnt2+1,y)-lsh2-1;
	if(posx&&posy) ans=(ans+pre[posx][posy][0]*power(a,x-lsh1[posx])%mod*power(b,y-lsh2[posy])%mod)%mod;
	if(posx&&posy<cnt2) ans=(ans+pre[posx][posy+1][1]*power(a,x-lsh1[posx])%mod*power(b,lsh2[posy+1]-y)%mod)%mod;
	if(posx<cnt1&&posy) ans=(ans+pre[posx+1][posy][2]*power(a,lsh1[posx+1]-x)%mod*power(b,y-lsh2[posy])%mod)%mod;
	if(posx<cnt1&&posy<cnt2) ans=(ans+pre[posx+1][posy+1][3]*power(a,lsh1[posx+1]-x)%mod*power(b,lsh2[posy+1]-y)%mod)%mod;
	return ans;
}
signed main()
{
	freopen("satellite.in","r",stdin); freopen("satellite.out","w",stdout);
	n=read(); q=read(); w=read(); h=read(); mod=read(); a=read(); b=read(); pa1[0]=pa2[0]=pb1[0]=pb2[0]=1;
	for(int i=1;i<=n;i++) s[i].h=read(),s[i].x=read(),s[i].y=read(),lsh1[++cnt1]=s[i].x,lsh2[++cnt2]=s[i].y;
	sort(lsh1+1,lsh1+cnt1+1); cnt1=unique(lsh1+1,lsh1+cnt1+1)-lsh1-1;
	sort(lsh2+1,lsh2+cnt2+1); cnt2=unique(lsh2+1,lsh2+cnt2+1)-lsh2-1;
	for(int i=1;i<=base;i++) pa2[i]=pa2[i-1]*a%mod,pb2[i]=pb2[i-1]*b%mod;
	for(int i=1;i<=base;i++) pa1[i]=pa1[i-1]*pa2[base]%mod,pb1[i]=pb1[i-1]*pb2[base]%mod;
	for(int i=1;i<=n;i++)
		s[i].x=lower_bound(lsh1+1,lsh1+cnt1+1,s[i].x)-lsh1,
		s[i].y=lower_bound(lsh2+1,lsh2+cnt2+1,s[i].y)-lsh2,
		val[s[i].x][s[i].y]=(val[s[i].x][s[i].y]+s[i].h)%mod;
	for(int i=1;i<=cnt1;i++)
		for(int j=1;j<=cnt2;j++)
		{
			int pa=power(a,lsh1[i]-lsh1[i-1]),pb=power(b,lsh2[j]-lsh2[j-1]);
			pre[i][j][0]=(val[i][j]+pre[i-1][j][0]*pa%mod+pre[i][j-1][0]*pb%mod-pre[i-1][j-1][0]*pa%mod*pb%mod+mod)%mod;
		}
	for(int i=1;i<=cnt1;i++)
		for(int j=cnt2;j>=1;j--)
		{
			int pa=power(a,lsh1[i]-lsh1[i-1]),pb=power(b,lsh2[j+1]-lsh2[j]);
			pre[i][j][1]=(val[i][j]+pre[i-1][j][1]*pa%mod+pre[i][j+1][1]*pb%mod-pre[i-1][j+1][1]*pa%mod*pb%mod+mod)%mod;
		}
	for(int i=cnt1;i>=1;i--)
		for(int j=1;j<=cnt2;j++)
		{
			int pa=power(a,lsh1[i+1]-lsh1[i]),pb=power(b,lsh2[j]-lsh2[j-1]);
			pre[i][j][2]=(val[i][j]+pre[i+1][j][2]*pa%mod+pre[i][j-1][2]*pb%mod-pre[i+1][j-1][2]*pa%mod*pb%mod+mod)%mod;
		}
	for(int i=cnt1;i>=1;i--)
		for(int j=cnt2;j>=1;j--)
		{
			int pa=power(a,lsh1[i+1]-lsh1[i]),pb=power(b,lsh2[j+1]-lsh2[j]);
			pre[i][j][3]=(val[i][j]+pre[i+1][j][3]*pa%mod+pre[i][j+1][3]*pb%mod-pre[i+1][j+1][3]*pa%mod*pb%mod+mod)%mod;
		}
	while(q--) printf("%lld\n",solve());
	return 0;
}
T3 是我的你不要抢
解题思路
直接 map 记忆化一下 Hash,对于每一个曾经有过的询问直接回答。
证明一下复杂度,假如串长都是 \(\le\sqrt{L}\) 那么 对于每一次询问的最大复杂度就是 \(\sqrt{L}\) 询问次数也就是 \(L\) 时间完全允许。
如果串长 \(\ge\sqrt{L}\) 询问最多也就有 \(L\) 个,证明类似于上面的。
code
#include<bits/stdc++.h>
#include<bits/extc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
using namespace __gnu_pbds;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
const int N=6e5+10,M=1e3+10;
const ull base=133331;
int n,m,q,l[N];
ull p[N];
string ch;
vector<string> v;
vector<ull> has[N];
gp_hash_table<int,int> mp[N];
int solve(int x,int y)
{
	int lim=min(l[x],l[y]);
	for(int len=lim;len;len--)
		if(has[x][l[x]]-has[x][l[x]-len]*p[len]==has[y][len])
			return len;
	return 0;
}
signed main()
{
	freopen("string.in","r",stdin); freopen("string.out","w",stdout);
	n=read(); q=read(); v.push_back(ch); p[0]=1;
	for(int i=1;i<=n;i++) cin>>ch,v.push_back(ch),l[i]=ch.size(),m=max(m,l[i]);
	for(int i=1;i<=m;i++) p[i]=p[i-1]*base;
	for(int i=1;i<=n;i++)
	{
		v[i]=" "+v[i]; has[i].push_back(0);
		for(int j=1;j<=l[i];j++) has[i].push_back(has[i][j-1]*base+v[i][j]);
	}
	while(q--)
	{
		int x,y; x=read(); y=read();
		if(mp[x].find(y)==mp[x].end()) mp[x].insert(make_pair(y,solve(x,y)));
		printf("%lld\n",mp[x].find(y)->second);
	}
	return 0;
}
T4 显然也是我整的
解题思路
这个题。。。题解咋说就咋整就行了,别的就。。


code
#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
using namespace std;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
const int N=2e5+10;
int n,m,T,top,sta[N],s[N];
set<int> se;
void work(int &ans,int &n)
{
	int num=(*se.begin()),temp=2*num-n;
	for(auto it=se.begin();it!=se.end();it++) sta[++top]=(*it);
	ans+=temp; n-=temp; se.clear();
	for(int i=1;i<=top;i++) se.insert(sta[i]-temp);
}
int solve(int n)
{
	int ans=top=0,gcd=0;
	if((*se.begin())>n/2) work(ans,n);
	for(auto it=se.begin();it!=se.end();it++)
		if((*it)<=n/2) gcd=__gcd(gcd,(*it));
		else break;
	se.erase(se.begin(),se.upper_bound(n/2));
	for(auto it=se.begin();it!=se.end();it++)
		if((*it)+gcd<=n) gcd=__gcd(gcd,(*it));
		else break;
	se.erase(se.begin(),se.upper_bound(n-gcd));
	if(!se.size()) return ans+gcd;
	int temp=gcd+n%gcd; top=0;
	for(auto it=se.begin();it!=se.end();it++) sta[++top]=(*it);
	se.clear(); for(int i=1;i<=top;i++) se.insert(temp+sta[i]-n); se.insert(gcd);
	return ans+solve(temp);
}
signed main()
{
	freopen("graph.in","r",stdin); freopen("graph.out","w",stdout);
	T=read();
	while(T--)
	{
		n=read(); m=read(); se.clear();
		for(int i=1;i<=m;i++) s[i]=read();
		for(int i=1;i<=m;i++) se.insert(s[i]);
		printf("%lld\n",solve(n));
	}
	return 0;
}
NOIP模拟72的更多相关文章
- Noip模拟72 2021.10.9
		T1 出了个大阴间题 真就以为他出了个大阴间题就没写,打个暴力就跑了 数据范围显然摆明是状压 设$f[sta][0/1]$表示在已经选择的集合$sta$中,$A$的最大值是$A$还是$A+1$ 然后按 ... 
- 2021.10.9考试总结[NOIP模拟72]
		T1出了个大阴间题 状压\(DP\),记当前状态的代价和与方案数.状态\(\Theta(2^nn)\),转移\(\Theta(n)\). 发现每个状态的最大值只会是所选集合的\(max\)或加一.于是 ... 
- NOIP模拟17.9.22
		NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥ 
- NOIP 模拟4 T2
		本题属于二和一问题 子问题相互对称 考虑对于问题一:知a求b 那么根据b数组定义式 显然能发现问题在于如何求dis(最短路) 有很多算法可供选择 dijsktra,floyed,bfs/dfs,spf ... 
- NOIP模拟赛20161022
		NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ... 
- contesthunter暑假NOIP模拟赛第一场题解
		contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ... 
- NOIP模拟赛 by hzwer
		2015年10月04日NOIP模拟赛 by hzwer (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ... 
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
		数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ... 
- 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1
		题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ... 
随机推荐
- git撤销已经push到远程仓库上的代码
			具体方法,git命令:git reset --hard <commit_id>git push origin HEAD --force commit_id可以通过git命令:git log ... 
- 刷题-力扣-1137. 第 N 个泰波那契数
			1137. 第 N 个泰波那契数 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/n-th-tribonacci-number 著作权 ... 
- vscode如何配置ts的lint,如何配置才能让eslint和prettier不冲突一键格式化代码(vue开发使用)
			最近在使用ts,发觉tslint在vscode上使用很不方便,不如eslint一键格式化高效,就想着能不能配置下vscode让其像写js一样爽 这篇文章主要解决2个问题,第一个是如何让vscode使用 ... 
- 关于innodb中MVCC的一些理解
			一.MVCC简介 MVCC (Multiversion Concurrency Control),即多版本并发控制技术,它使得大部分支持行锁的事务引擎,不再单纯的使用行锁来进行数据库的并发控制,取而代 ... 
- centos7 netstat
			netstat 是控制台命令,它可以显示路由表.实际的网络连接以及每一个网络接口设备的状态信息.Netstat 用于显示与 IP . TCP . UDP 和 ICMP 协议相关的统计数据,一般用于检验 ... 
- Android Parsing between JSON and Kotlin Object with Google Gson Library
			Parsing between JSON and Kotlin Object with Google Gson Library dependencies { ... implementation 'c ... 
- mybaits源码分析--事务管理(八)
			一.事务管理 写到这也快进入收尾阶段了了,在介绍MyBatis中的事务管理时不可避免的要接触到DataSource的内容,所以接下来会分别来介绍DataSource和Transaction两块内容. ... 
- python类、继承
			Python 是一种面向对象的编程语言.Python 中的几乎所有东西都是对象,拥有属性和方法.类(Class)类似对象构造函数,或者是用于创建对象的"蓝图". 一.python ... 
- ELK学习之Logstash篇
			Logstash在ELK这一整套解决方案中作为数据采集终端,支持对接Kafka.数据库(MySQL.Oracle).文件等等. 而在Logstash内部的数据流转,主要经过三个环节:input -&g ... 
- ubantu硬盘不足,无法启动
			我的ubantu虚拟机经过我一顿操作后,就起不来了.然后经过多方询问,广集天下良方,最终发现是由于分配的硬件空间不足导致的.现象如下: 通过查看 root@ubantu:/snap# df -h Fi ... 
