T1 石子游戏

大坑未补

T2 大鱼吃小鱼

解题思路

set+桶可以得到 60pts (code)

线段树上二分每一次优先递归右区间从右区间贪心选择,并且记录下更改过的值,在处理完答案之后再复原回去。

处理的时候类似于区间覆盖 laz 标记。

同时用 set 维护一个有序数组用于查看当前值的下一个应该选哪个

code

#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"<<endl
#define ls x<<1
#define rs x<<1|1
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=8e6+10,INF=1e18;
int n,m,ans,top,now,cnt,sta[N],s[N],lsh[N];
struct Ques{int opt,x,y;}q[N];
struct Node{int dat,bas,laz;}ys[N];
multiset<int> res;
bool can=true,jud=true;
struct Segment_Tree
{
bool vis[N<<2]; Node tre[N<<2];
int ceil(int x,int y){return x/y+(x%y!=0);}
void push_up(int x)
{
if(can&&!vis[x]) sta[++top]=x,ys[top]=tre[x],vis[x]=true;
tre[x].dat=tre[ls].dat+tre[rs].dat;
tre[x].bas=tre[ls].bas+tre[rs].bas;
}
void push_down(int x)
{
if(!tre[x].laz) return ;
if(!vis[ls]) sta[++top]=ls,ys[top]=tre[ls],vis[ls]=true;
if(!vis[rs]) sta[++top]=rs,ys[top]=tre[rs],vis[rs]=true;
tre[ls].dat=tre[rs].dat=tre[ls].bas=tre[rs].bas=0; tre[ls].laz=tre[rs].laz=1; tre[x].laz=0;
}
void insert(int x,int l,int r,int pos,int val)
{
if(l==r) return tre[x].bas+=val,tre[x].dat+=val*lsh[l],void();
int mid=(l+r)>>1;
if(pos<=mid) insert(ls,l,mid,pos,val);
else insert(rs,mid+1,r,pos,val);
push_up(x);
}
int query(int x,int l,int r,int L,int R)
{
if(L>R||!tre[x].dat) return 0;
if(L<=l&&r<=R) return tre[x].dat;
int mid=(l+r)>>1,sum=0; push_down(x);
if(L<=mid) sum+=query(ls,l,mid,L,R);
if(R>mid) sum+=query(rs,mid+1,r,L,R);
return sum;
}
void solve(int x,int l,int r,int L,int R,int &need)
{
if(l==r)
{
if(tre[x].dat<need) goto V;
if(!vis[x]) sta[++top]=x,ys[top]=tre[x],vis[x]=true;
int temp=ceil(need,lsh[l]);
tre[x].bas-=temp; ans+=temp;
now+=temp*lsh[l]; need-=temp*lsh[l];
jud=false; tre[x].dat=tre[x].bas*lsh[l];
return ;
} V:;
if(r<=R&&tre[x].dat<=need)
{
need-=tre[x].dat; now+=tre[x].dat;
if(need<=0) jud=true; ans+=tre[x].bas;
if(!vis[x]) sta[++top]=x,ys[top]=tre[x],vis[x]=true;
tre[x].dat=tre[x].bas=0; tre[x].laz=1; return ;
}
int mid=(l+r)>>1; push_down(x);
if(R<=mid) return solve(ls,l,mid,L,R,need),push_up(x),void();
if(jud) solve(rs,mid+1,r,L,R,need);
if(jud) solve(ls,l,mid,L,R,need);
push_up(x);
}
}T;
void Restore()
{
for(int i=1;i<=top;i++)
T.tre[sta[i]]=ys[i],
T.vis[sta[i]]=false,T.tre[sta[i]].laz=0;
}
void solve(int bas,int goal)
{
if(bas>=goal) return printf("0\n"),void();
int temp=goal-bas,rec,need; now=bas; ans=top=0;
while(temp>0&&now<goal)
{
auto it=res.lower_bound(now);
if(it!=res.end()) rec=*it;
else rec=INF;
need=min(temp,rec-now+1); jud=true;
int las=need,pos=lower_bound(lsh+1,lsh+cnt+1,now)-lsh-1;
if(!pos) break;
T.solve(1,1,cnt,1,pos,need);
if(need>0||it==res.end()) break;
temp-=las-need;
}
Restore();
if(need<=0) printf("%lld\n",ans); else printf("-1\n");
}
signed main()
{
freopen("fish.in","r",stdin); freopen("fish.out","w",stdout);
n=read();
for(int i=1;i<=n;i++) s[i]=read(),lsh[++cnt]=s[i],res.insert(s[i]);
m=read();
for(int i=1;i<=m;i++)
{
q[i].opt=read(); q[i].x=read();
if(q[i].opt==1) q[i].y=read();
lsh[++cnt]=q[i].x;
}
lsh[++cnt]=INF; sort(lsh+1,lsh+cnt+1); cnt=unique(lsh+1,lsh+cnt+1)-lsh-1; can=false;
for(int i=1;i<=n;i++) T.insert(1,1,cnt,lower_bound(lsh+1,lsh+cnt+1,s[i])-lsh,1);
can=true;
for(int i=1;i<=m;i++)
{
int opt=q[i].opt,x=q[i].x,y=q[i].y;
if(opt==1){solve(x,y);continue;}
if(opt==2)
{
can=false; T.insert(1,1,cnt,lower_bound(lsh+1,lsh+cnt+1,x)-lsh,1);
res.insert(x); can=true; continue;
}
can=false; T.insert(1,1,cnt,lower_bound(lsh+1,lsh+cnt+1,x)-lsh,-1);
res.erase(res.find(x)); can=true;
}
return 0;
}

T3 黑客

解题思路

大水题。。

对于 \([1,999]\) 区间内任意两个互质的数,分别求出在 \([a,b],[c,d]\) 两个区间中的上下界。

取一个交集乘上对应的贡献就是答案了。

code

#include <bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Failed"
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=1e3+10,mod=1e9+7;
int a,b,c,d,ans;
vector<pair<int,int> > v;
inline void add(int &x,int y){x+=y;if(x>mod)x-=mod;}
signed main()
{
freopen("hacker.in","r",stdin); freopen("hacker.out","w",stdout);
a=read(); b=read(); c=read(); d=read();
for(int i=1;i<=999;i++)
for(int j=1;j<=999-i;j++)
if(__gcd(i,j)==1)
v.push_back(make_pair(i,j));
for(int i=0;i<v.size();i++)
{
int x=v[i].first,y=v[i].second;
int lima=ceil((1.0*a)/(1.0*x)),limb=floor((1.0*b)/(1.0*x));
int limc=ceil((1.0*c)/(1.0*y)),limd=floor((1.0*d)/(1.0*y));
int l=max(lima,limc),r=min(limb,limd);
if(l<=r) add(ans,(r-l+1)%mod*(x+y)%mod);
}
printf("%lld",ans);
return 0;
}

T4 黑客(续)

解题思路

丧心病狂考高精。。(改题的时候是我第一次打高精,竟然一遍过??)

数位 DP ,DP 方式有两种:传当前数字的状态或者对于后面数字的限制。

显然第二种 DP 复杂度是优于第一种的,但是第一种直接 __int128 强行压 17 位竟然可以过掉。。

经过本人实测倒数第三个测试点 dfs 函数 方法一调用了大约 25000 次,而方法二竟然只调用了 199次。

可谓天壤之别,剩下的就是板子了。。

code

#include <bits/stdc++.h>
#define ull unsigned long long
#define f() cout<<"Failed"
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=5e2+10,M=1000;
int n,m,k,can[10];
bool vis[10][10],pas[N][1<<9];
struct Node
{
int a[M+10];
void clear(){memset(a,0,sizeof(a));}
inline Node friend operator << (Node x,int val)
{
if(!val) return x;
int lim=M; while(lim&&!x.a[lim]) lim--;
for(int i=lim;i>=1;i--) x.a[i+val]=x.a[i];
for(int i=1;i<=val;i++) x.a[i]=0; return x;
}
inline Node friend operator * (Node x,int y)
{
int lim=M; while(lim&&!x.a[lim]) lim--;
Node z; z.clear(); lim+=10;
for(int i=1;i<=lim;i++) z.a[i]=x.a[i]*y;
for(int i=1;i<=lim;i++) z.a[i+1]+=z.a[i]/10,z.a[i]%=10;
return z;
}
inline Node friend operator + (Node x,Node y)
{
int lim=M; while(lim&&!x.a[lim]&&!y.a[lim]) lim--;
Node z; z.clear(); lim++;
for(int i=1;i<=lim;i++) z.a[i]=x.a[i]+y.a[i];
for(int i=1;i<=lim;i++) z.a[i+1]+=z.a[i]/10,z.a[i]%=10;
return z;
}
void print()
{
int lim=M; while(lim>1&&!a[lim]) lim--;
for(int i=lim;i>=1;i--) printf("%d",a[i]);
printf("\n");
}
}f[N][1<<9],g[N][1<<9];
void dfs(int x,int lim)
{
if(pas[x][lim]) return ; pas[x][lim]=true;
if(x==n+1) return f[x][lim].a[1]=1,void();
for(int i=1;i<=k;i++)
{
if((lim>>i-1)&1) continue;
int p1=x+1,p2=lim|can[i]; dfs(p1,p2);
f[x][lim]=f[x][lim]+f[p1][p2];
g[x][lim]=g[x][lim]+(f[p1][p2]<<(n-x))*i+g[p1][p2];
}
return ;
}
signed main()
{
freopen("hacker2.in","r",stdin); freopen("hacker2.out","w",stdout);
n=read(); m=read(); k=read();
for(int i=1,a,b;i<=m;i++) a=read(),b=read(),can[a]|=1<<(b-1);
dfs(1,0); f[1][0].print(); g[1][0].print();
return 0;
}

PS

尽管这一天是我生日,要是没有 星痕Force_A 的提醒还真就忘了。。

NOIP模拟69的更多相关文章

  1. Noip模拟69 2021.10.5

    考场拼命$yy$高精度结果没学好$for$循环痛失$50pts$,当场枯死 以后一定打对拍,要不考后会... T1 石子游戏 首先要知道典型的$NIM$博弈,就是说如果所有堆石子个数的异或和为$0$则 ...

  2. NOIP模拟17.9.22

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

  3. NOIP 模拟4 T2

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

  4. NOIP模拟赛20161022

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

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

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

  6. NOIP模拟赛 by hzwer

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

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

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

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

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

  9. 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...

随机推荐

  1. 【springcloud】Zuul高级配置(zuul--3)

    转自:https://blog.csdn.net/pengjunlee/article/details/87285673 为路由提供HystrixFallback 当Zuul中某一个路由的断路器被断开 ...

  2. JavaWeb 三大器--Listener、Filter 和Interceptor 总结

    说明:web.xml的加载顺序是:[Context-Param]->[Listener]->[Filter]->[Servlet],而同个类型之间的实际程序调用的时候的顺序是根据对应 ...

  3. 使用dom4j工具:读取xml标签(二)

    package dom4j_read; import java.io.File; import java.util.List; import org.dom4j.Document; import or ...

  4. deepin-terminal改造风云再起

    1. 创作背景 使用deepin-terminal的时候,我发现一些小的问题. 在论坛的帖子(https://bbs.deepin.org/zh/post/224502)也总结反馈了这些问题 终端标签 ...

  5. windows下mysql5.7.17配置

    1.官网下载mysql5.7.17 64位 https://dev.mysql.com/downloads/mysql/ 2.安装完解压到E盘主目录下,改文件名为mysql 3.配置环境变量 我的电脑 ...

  6. promise小案例

    页面中有个板块,需要多张图片加载完之后才能进行显示 //页面中有个板块 需要多张图片加载完之后才能进行显示 const loadImg = (src) => { return new Promi ...

  7. python manage.py migrate出错

    python manage.py migrate出错 在建立Django项目过程中执行 python manage.py migrate命令,出现如下错误: 解决办法: 编辑D:\install fi ...

  8. 一、docker部署Jenkins

    1.部署启动脚本: [root@node10 docker-data]# cat start.sh docker run -d \ --restart=unless-stopped \ -v /opt ...

  9. Linux 安装 Harbor 私有镜像仓库

    下载 最新发行:https://github.com/goharbor/harbor/releases # 下载文件 wget https://github.com/goharbor/harbor/r ...

  10. Spring AOP 事务配置(实现转账事务)

    1. 事务特性 事务特性:ACID 原子性:整体 [原子性是指事务包含的所有操作要么全部成功,要么全部失败] 一致性:数据 [一个事务执行之前和执行之后都必须处于一致性状态] 隔离性:并发 [对于任意 ...