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中的静态内部类

    静态内部类是 static 修饰的内部类,这种内部类的特点是: 1. 静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问 2. 如果外部类的静态成员与内部类的成 ...

  2. Git pull and push

    转自:https://blog.csdn.net/qq_41306423/article/details/101701991 关于 git pull 和 git pull origin develop ...

  3. Linux centos7 find 命令

    2021-08-13 1. 命令简介 find 命令用来在指定目录下查找文件.任何位于参数之前的字符串都将被视为欲查找的目录名.如果使用该命令时,不设置任何参数,则 find 命令将在当前目录下查找子 ...

  4. centos7系统上pgsql的一些报错解决方法

    1.2021-07-15 # 问题: 登录时服务器拒绝连接 psql -h 192.168.1.112 # 解决方法:修改配置文件 pg_hba.conf ,将该主机加进白名单 vi pg_hba.c ...

  5. mybaits源码分析--事务管理(八)

    一.事务管理 写到这也快进入收尾阶段了了,在介绍MyBatis中的事务管理时不可避免的要接触到DataSource的内容,所以接下来会分别来介绍DataSource和Transaction两块内容. ...

  6. sed命令的使用

    1.sed格式.理解 (1)找谁  干什么 (2)想找谁,就把谁保护起来 2.sed基本操作 操作文件oldboy.txt I am lizhenya teacher! I teach linux. ...

  7. Flask - 访问返回字典的接口报错:The view function did not return a valid response. The return type must be a string, tuple, Response instance, or WSGI callable, but it was a dict.

    背景 有一个 Flask 项目,然后有一个路由返回的是 dict 通过浏览器访问,结果报错 关键报错信息 TypeError: 'dict' object is not callable The vi ...

  8. Springcloud轻松上手

    Springcloud技术分享 Spring Cloud 是一套完整的微服务解决方案,基于 Spring Boot 框架,准确的说,它不是一个框架,而是一个大的容器,它将市面上较好的微服务框架集成进来 ...

  9. uni-app 登录Abp VNexe并获取Token

    uni.request方式登录abp关键代码如下,因abp获取token需要用formdata方式请求所以需要加上请求头 const baseUrl = 'http://127.0.0.1:44323 ...

  10. el-upload + accept限制上传的文件格式

    /**  * kevin 2021/1/4  * @description el-upload + accept限制上传的文件格式  * @param e 校验的类型  * @returns {str ...