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的更多相关文章

  1. Noip模拟72 2021.10.9

    T1 出了个大阴间题 真就以为他出了个大阴间题就没写,打个暴力就跑了 数据范围显然摆明是状压 设$f[sta][0/1]$表示在已经选择的集合$sta$中,$A$的最大值是$A$还是$A+1$ 然后按 ...

  2. 2021.10.9考试总结[NOIP模拟72]

    T1出了个大阴间题 状压\(DP\),记当前状态的代价和与方案数.状态\(\Theta(2^nn)\),转移\(\Theta(n)\). 发现每个状态的最大值只会是所选集合的\(max\)或加一.于是 ...

  3. NOIP模拟17.9.22

    NOIP模拟17.9.22 前进![问题描述]数轴的原点上有一只青蛙.青蛙要跳到数轴上≥

  4. NOIP 模拟4 T2

    本题属于二和一问题 子问题相互对称 考虑对于问题一:知a求b 那么根据b数组定义式 显然能发现问题在于如何求dis(最短路) 有很多算法可供选择 dijsktra,floyed,bfs/dfs,spf ...

  5. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  6. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  7. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  8. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  9. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

随机推荐

  1. java输入字符

    1.创建一个Scanner对象. 2.调用.next()返回一个String类型用一个变量接受. 3.调用该String变量的.charAt(0),获取第一个字符. Scanner scn=new S ...

  2. SpringBoot 优雅配置跨域多种方式及Spring Security跨域访问配置的坑

    前言 最近在做项目的时候,基于前后端分离的权限管理系统,后台使用 Spring Security 作为权限控制管理, 然后在前端接口访问时候涉及到跨域,但我怎么配置跨域也没有生效,这里有一个坑,在使用 ...

  3. 高性能利器:CDN我建议你好好学一下!

    硬核干货分享,欢迎关注[Java补习课]成长的路上,我们一起前行 ! <高可用系列文章> 已收录在专栏,欢迎关注! CDN 概述 CDN 全称 Content Delivery Netwo ...

  4. MySQL高可用主从复制部署

    原文转自:https://www.cnblogs.com/itzgr/p/10233932.html作者:木二 目录 一 基础环境 二 实际部署 2.1 安装MySQL 2.2 初始化MySQL 2. ...

  5. MySQL-SQL基础

    mysql> use test; Database changed mysql> create table emp(ename varchar(10),hirdate date,sal d ...

  6. TCP连接中的状态

    1. 正常状态转换 我们用图 3-13 来显示在正常的 TCP 连接的建立与终止过程中,客户与服务器所经历的不同状态.读者可以对照图 3-12 来阅读,使用图 3-12 的状态图来跟踪图 3-13 的 ...

  7. IPv6 QoS 多媒体应用:性能分析 (上)

    IPv6 QoS 多媒体应用:性能分析   Assured Forwarding (AF):保证转发 Expedited Forwarding (EF):快速转发 Traffic aggregatio ...

  8. Git - Mac 电脑使用 brew 更新 Git

    安装 Homebrew Homebrew 是一个软件包管理器.它的作用就是将软件包安装到自己的目录中,然后将其文件符号链接到 /usr/local.更多信息,请自行进入官网查看 https://bre ...

  9. Mybatis-基本学习(上)

    目录 Mybatis mybatis开始 -----环境准备 一.简介 1.什么是MyBatis 2.持久化 3.持久层 4.为什么需要Mybatis? 二.第一个Mybatis程序 1.搭建环境 1 ...

  10. python库--flashtext--大规模数据清洗利器

    flashtext.keyword (flashtext) 类/方法 返回值 参数 说明 .KeywordProcessor() 对象kp case_sensitive=False 是否区分大小写 添 ...