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. 刷题-力扣-107. 二叉树的层序遍历 II

    107. 二叉树的层序遍历 II 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/binary-tree-level-order-tr ...

  2. .NetCore3.1获取文件并重新命名以及大批量更新及写入数据

    using Microsoft.AspNetCore.Mvc; using MySql.Data.MySqlClient; using System; using System.Collections ...

  3. 用C++实现的Eratosthenes筛法程序

    运行示例 只输出素数总数的运行示例 PS H:\Read\num\x64\Release> .\esieve.exe Eratosthenes sieve: a method to find o ...

  4. 2021年哪个低代码平台更值得关注?T媒体盘点国内主流低代码厂商

    2020年圣诞前夜,国内知名创投科技媒体T媒体旗下的T研究发布了2020中国低代码平台指数测评报告.报告除了对国内低代码行业现状进行总结外,还对主流低代码厂商的市场渗透和曝光进行测评. 报告认为,低代 ...

  5. docker-harbor私有仓库使用笔记

    1. 登录harbor管理页面,创建项目,比如yuqx_test 2. admin登录,此处免密登录,正常情况下会输入账号密码 [root@k8s-rancher2 ~]# docker login ...

  6. Java clone() 方法克隆对象——深拷贝与浅拷贝

    基本数据类型引用数据类型特点 1.基本数据类型的特点:直接存储在栈(stack)中的数据 2.引用数据类型的特点:存储的是该对象在栈中引用,真实的数据存放在堆内存里 引用数据类型在栈中存储了指针,该指 ...

  7. 面试官:Redis的事务满足原子性吗?

    原创:码农参上(微信公众号ID:CODER_SANJYOU),欢迎分享,转载请保留出处. 谈起数据库的事务来,估计很多同学的第一反应都是ACID,而排在ACID中首位的A原子性,要求一个事务中的所有操 ...

  8. 一个Django项目中实现的简单HTML页面布局

    1 - 基础页面(被继承的模板) {% load static %} <!DOCTYPE html> <html lang="en"> <head&g ...

  9. 单片机学习(十二)1-Wire通信协议和DS18B20温度传感器

    目录 一.DS18B20 1. DS18B20简介 2. 电路原理图 3. 内部结构 内部完整结构框图 存储器结构 二.单总线(1-Wire BUS) 1. 单总线简介 2. 电路规范 3. 单总线的 ...

  10. Linux串口调试详解

    测试平台 宿主机平台:Ubuntu 16.04.6 目标机:iMX6ULL 目标机内核:Linux 4.1.15 目标机添加串口设备 一般嵌入式主板的默认镜像可能只配置了调试串口,并用于 consol ...