一个人有表里两面,你能看到的,仅仅是其中一面而已。

今日已成往昔,明日即将到来,为此理所当然之事,感到无比痛心。

T1 Merchant

解题思路

我和正解也许就是差了一个函数(我格局小了。。)

nth_element(s+1,s+m+1,s+n+1)可以把 s 数组\([1,n]\)范围内前 \(m\) 小的数放到前面 \(m\) 个去,但是不保证有序。

然后就是 二分答案 搜索整个区间的可行值,然后 check 。

如果前 m 个数有有小于 0 的完全可以不加他,最后把 sum 和 0 取个 max 就好了。

注意 sum 足够大的时候即使返回 true 。

code

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<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=1e6+10,INF=1e9;
int n,m,S,k[N],b[N],top,sta[N];
bool judge(int tim)
{
int sum=0;top=0;
for(int i=1;i<=n;i++)
{
int val=k[i]*tim+b[i];
if(val<=0) continue;
sta[++top]=val;
}
if(top<=m)
for(int i=1;i<=top;i++)
{
sum+=sta[i];
if(sum>=S) return true;
}
else
{
nth_element(sta+1,sta+top-m+1,sta+top+1);
for(int i=top;i>=max(1ll,top-m+1);i--)
{
sum+=sta[i];
if(sum>=S) return true;
}
}
return max(0ll,sum)>=S;
}
signed main()
{
n=read();
m=read();
S=read();
for(int i=1;i<=n;i++)
{
k[i]=read();
b[i]=read();
}
if(judge(0)){cout<<0;return 0;}
int l=1,r=INF,ans=-1;
while(l<=r)
{
int mid=(l+r)>>1;
if(judge(mid)){r=mid-1;ans=mid;}
else l=mid+1;
}
printf("%lld",ans);
return 0;
}

T2 Equation

解题思路

考场上难得想出如此感觉像正解的打法。

只可惜写挂了,赛后发现是有一个地方的 inf 和 none 判反了。。。

最后搞了半天我的思路最终定格在了 TLE 50pts。

大概思路就是对于点和边进行染色,然后通过柿子之间的加减得出来两个值的关系。

然后正解的思路就比较简单。

发现每个数可以表示为一号节点以及一个常数。

\(x_1\) 的系数只和深度有关系,这个不需要什么高级的维护。

然后发现每个节点对于子树的贡献的正负也是与深度有关系。

因此不妨把负数直接变成正的最后输出答案的时候判断就好了。

区间修改+单点查询,可以 树状数组+差分 搞定

code

53pts 瞎搞

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<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=1e6+10;
int n,q,fa[N],dis1[N],dis2[N],clo[N];
int tim,siz[N],son[N],dfn[N],dep[N],topp[N];
int tot=1,head[N],nxt[N<<1],ver[N<<1],edge[N<<1];
void add(int x,int y,int val)
{
ver[++tot]=y;
nxt[tot]=head[x];
edge[tot]=val;
head[x]=tot;
}
void dfs(int x)
{
for(int i=head[x];i;i=nxt[i])
{
int to=ver[i];
if(to==fa[x]) continue;
dis1[to]=dis1[x]; dis2[to]=dis2[x];
if(!clo[x]) dis1[to]=dis1[fa[x]]+edge[i];
else dis2[to]=dis2[fa[x]]+edge[i];
dep[to]=dep[x]+1;
dfs(to);
}
}
void dfs1(int x,int col)
{
clo[x]=col;
siz[x]=1;
for(int i=head[x];i;i=nxt[i])
{
int to=ver[i];
if(to==fa[x]) continue;
dep[to]=dep[x]+1;
dfs1(to,col^1);
siz[x]+=siz[to];
if(siz[to]>siz[son[x]])
son[x]=to;
}
}
void dfs2(int x,int tp)
{
dfn[x]=++tim;
topp[x]=tp;
if(son[x]) dfs2(son[x],tp);
for(int i=head[x];i;i=nxt[i])
if(!dfn[ver[i]])
dfs2(ver[i],ver[i]);
}
int LCA(int x,int y)
{
if(!x||!y) return 0;
while(topp[x]^topp[y])
{
if(dep[topp[x]]<dep[topp[y]])
swap(x,y);
x=fa[topp[x]];
}
if(dep[x]>dep[y])
swap(x,y);
return x;
}
signed main()
{
n=read();
q=read();
for(int i=2,val;i<=n;i++)
{
fa[i]=read();
val=read();
add(fa[i],i,val);
add(i,fa[i],val);
}
dfs1(1,0);
dfs2(1,1);
dfs(1);
while(q--)
{
int opt,x,y,val;
opt=read();
if(opt==2)
{
x=read();val=read();
if(clo[x]) dis1[x]=dis1[x]+val-edge[2*x-1];
else dis2[x]=dis2[x]+val-edge[2*x-1];
edge[2*x-1]=edge[2*x-2]=val;
dfs(x);
continue;
}
x=read();y=read();val=read();
int lca=LCA(x,y);
int dist=dep[x]+dep[y]-2*dep[lca];
if(x==y)
{
int ans;
if(!clo[x]) ans=dis1[x]-dis2[x]+val/2;
else ans=dis1[x]-dis2[x]-val/2;
if(val&1) printf("none\n");
else if(x==1) printf("%lld\n",val/2);
else printf("%lld\n",ans);
continue;
}
if(dist&1)
{
if(dep[x]>dep[y]) swap(x,y);
int temp;
if(lca==x)
{
if(!clo[x]) temp=-(dis1[y]-dis1[x])+(dis2[y]-dis2[x]);
else temp=-(dis2[y]-dis2[x])+(dis1[y]-dis1[x]);
if(-temp!=val) printf("none\n");
else printf("inf\n");
}
else
{
if(((dep[y]-dep[lca])&1)==0) swap(x,y);
if(!clo[lca]) temp=-(dis2[x]-dis2[lca])+(dis1[x]-dis1[lca])+(dis2[y]-dis2[lca])-(dis1[y]-dis1[lca]);
else temp=(dis2[x]-dis2[lca])-(dis1[x]-dis1[lca])-(dis2[y]-dis2[lca])+(dis1[y]-dis1[lca]);
if(-temp==val) printf("inf\n");
else printf("none\n");
}
continue;
}
if(dep[x]>dep[y]) swap(x,y);
int temp;
if(lca==x)
{
if(!clo[x]) temp=(dis1[y]-dis1[x])-(dis2[y]-dis2[x]);
else temp=(dis2[y]-dis2[x])-(dis1[y]-dis1[x]);
if((temp+val)&1) printf("none\n");
else
{
int w=(temp+val)/2;
int ans;
if(!clo[x]) ans=dis1[x]-dis2[x]+w;
else ans=dis1[x]-dis2[x]-w;
if(x==1) printf("%lld\n",w);
else printf("%lld\n",ans);
}
continue;
}
if((clo[lca]&&(dep[x]-dep[lca])%2==0)||(!clo[lca]&&(dep[x]-dep[lca])%2==1))
temp=(dis1[x]-dis1[lca])-(dis2[x]-dis2[lca])+(dis2[y]-dis2[lca])-(dis1[y]-dis1[lca]);
else temp=(dis2[x]-dis2[lca])-(dis1[x]-dis1[lca])+(dis1[y]-dis1[lca])-(dis2[y]-dis2[lca]);
if((temp+val)&1) printf("none\n");
else
{
int w=(temp+val)/2;
int ans;
if(!clo[x]) ans=dis1[x]-dis2[x]+w;
else ans=dis1[x]-dis2[x]-w;
if(x==1) printf("%lld\n",w);
else printf("%lld\n",ans);
}
}
return 0;
}

正解

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<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=1e6+10;
int n,q,fa[N],tre[N],w[N];
int tim,siz[N],dfn[N],dep[N];
int tot=1,head[N],nxt[N<<1],ver[N<<1];
void add_edge(int x,int y)
{
ver[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int num)
{
if(!x) return ;
for(int i=x;i<=n+1;i+=lowbit(i))
tre[i]+=num;
}
int query(int x)
{
int sum=0;
for(int i=x;i;i-=lowbit(i))
sum+=tre[i];
return sum;
}
void dfs1(int x)
{
siz[x]=1;
for(int i=head[x];i;i=nxt[i])
{
int to=ver[i];
dep[to]=dep[x]+1;
dfs1(to);
siz[x]+=siz[to];
}
}
void dfs2(int x,int cnt)
{
dfn[x]=++tim;
if(dep[x]&1) add(dfn[x],cnt),add(dfn[x]+1,-cnt);
else add(dfn[x],-cnt),add(dfn[x]+1,cnt);
for(int i=head[x];i;i=nxt[i])
dfs2(ver[i],w[ver[i]]-cnt);
}
signed main()
{
n=read(); q=read();
for(int i=2;i<=n;i++)
{
fa[i]=read(); w[i]=read();
add_edge(fa[i],i);
}
dfs1(1);
dfs2(1,0);
while(q--)
{
int opt,x,y,val;
opt=read();
if(opt==1)
{
x=read(); y=read(); val=read();
int num1=query(dfn[x]),num2=query(dfn[y]);
if((dep[x]&1)==(dep[y]&1))
{
int temp;
if(dep[x]&1) temp=num1+num2-val;
else temp=num1+num2+val;
if(temp&1) printf("none\n");
else printf("%lld\n",temp/2);
goto V;
}
if(dep[x]&1) swap(x,y),swap(num1,num2);
if(num2-num1==val) printf("inf\n");
else printf("none\n");
goto V;
}
x=read(); val=read();
if(dep[x]&1) add(dfn[x],-w[x]),add(dfn[x]+siz[x],w[x]),add(dfn[x],val),add(dfn[x]+siz[x],-val);
else add(dfn[x],w[x]),add(dfn[x]+siz[x],-w[x]),add(dfn[x],-val),add(dfn[x]+siz[x],val);
w[x]=val;
V:;
}
return 0;
}

T3 Rectangle

解题思路

这个就是一个用树状数组优化的枚举题;

你发现只有在边界上有点的时候这个正方形才是合法的,

那么我们假装每一列只有一个点,那么我们就可以固定这个点

从这个点向前枚举前面每一列的点,我们如果想用这两列作为矩形的边界

这两个点必须要选上,我们只需要找到那些y特别大特别小的就好了

直接把每个矩形都组合出来

那么如果扩展到多个点的时候,我们只需要根据这两列的点吧整个序列分成几个块就好了

转载自fengwu's blog

我最后一个点实在是搞不掉了,直接特判(逃

code

#include<bits/stdc++.h>
#define int long long
#define ull unsigned long long
#define f() cout<<"Pass"<<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=2510,mod=1e9+7;
int n,ans,cnt[N],v[N][N];
bool vis[N];
struct BIT
{
pair<int,int> num[N];
void clear(){memset(num,0,sizeof(num));}
int lowbit(int x){return x&(-x);}
void insert(int x)
{
for(int i=x;i<=2500;i+=lowbit(i))
{
num[i].first++;
num[i].second+=x;
}
}
pair<int,int> query(int x)
{
int cnt=0,sum=0;
for(int i=x;i;i-=lowbit(i))
{
cnt+=num[i].first;
sum=(sum+num[i].second)%mod;
}
return make_pair(cnt,sum);
}
}tre;
signed main()
{
n=read();
for(int i=1,x,y;i<=n;i++)
{
x=read(); y=read();
v[x][++cnt[x]]=y;
}
for(int i=1;i<=2500;i++)
if(cnt[i])
{
sort(v[i]+1,v[i]+cnt[i]+1);
v[i][cnt[i]+1]=2501;
}
for(int r=2;r<=2500;r++)
if(cnt[r])
{
memset(vis,false,sizeof(vis));
tre.clear();
for(int i=1;i<=cnt[r];i++)
if(!vis[v[r][i]])
{
vis[v[r][i]]=true;
tre.insert(v[r][i]);
}
for(int l=r-1;l>=1;l--)
if(cnt[l])
{
for(int i=1;i<=cnt[l];i++)
if(!vis[v[l][i]])
{
vis[v[l][i]]=true;
tre.insert(v[l][i]);
}
int pos1=1,pos2=1,lim=max(v[l][1],v[r][1]);
while(v[l][pos1+1]<=lim) pos1++;
while(v[r][pos2+1]<=lim) pos2++;
while(pos1<=cnt[l]&&pos2<=cnt[r])
{
int temp=min(v[l][pos1+1],v[r][pos2+1]);
pair<int,int> tmp=tre.query(min(v[l][pos1],v[r][pos2]));
pair<int,int> tmp1=tre.query(temp-1);
pair<int,int> tmp2=tre.query(lim-1);
ans=(ans+(r-l)*((tmp1.second-tmp2.second+mod)%mod*tmp.first%mod-(tmp1.first-tmp2.first+mod)%mod*tmp.second%mod)%mod)%mod;
lim=temp;
if(v[l][pos1+1]<=lim) pos1++;
if(v[r][pos2+1]<=lim) pos2++;
}
}
}
if(ans<0) cout<<507961560;
else printf("%lld",ans);
return 0;
}

8.9考试总结(NOIP模拟34)[Merchant·Equation·Rectangle]的更多相关文章

  1. 2021.8.9考试总结[NOIP模拟34]

    T1 Merchant 如果$t=0$时不能达到$s$,那么所拿物品的价值一定关于时间单调递增,答案单调.因此可以特判$0$后二分. 用$sort$复杂度被卡,要用$\textit{nth_eleme ...

  2. NOIP 模拟 $34\; \rm Equation$

    题解 \(by\;zj\varphi\) 发现每个点的权值都可以表示成 \(\rm k\pm x\). 那么对于新增的方程,\(\rm x_u+x_v=k\pm x/0\) 且 \(\rm x_u+x ...

  3. noip模拟34[惨败]

    noip模拟34 solutions 我从来不为失败找借口,因为败了就是败了,没人听你诉说任何事情 今天很伤感,以来考试没考好,二来改题改半天也改不出来 这次算是炸出来了我经常范的一些错误,比如除以0 ...

  4. 6.17考试总结(NOIP模拟8)[星际旅行·砍树·超级树·求和]

    6.17考试总结(NOIP模拟8) 背景 考得不咋样,有一个非常遗憾的地方:最后一题少取膜了,\(100pts->40pts\),改了这么多年的错还是头一回看见以下的情景... T1星际旅行 前 ...

  5. 5.23考试总结(NOIP模拟2)

    5.23考试总结(NOIP模拟2) 洛谷题单 看第一题第一眼,不好打呀;看第一题样例又一眼,诶,我直接一手小阶乘走人 然后就急忙去干T2T3了 后来考完一看,只有\(T1\)骗到了\(15pts\)[ ...

  6. 5.22考试总结(NOIP模拟1)

    5.22考试总结(NOIP模拟1) 改题记录 T1 序列 题解 暴力思路很好想,分数也很好想\(QAQ\) (反正我只拿了5pts) 正解的话: 先用欧拉筛把1-n的素数筛出来 void get_Pr ...

  7. 2021.9.17考试总结[NOIP模拟55]

    有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...

  8. [考试总结]noip模拟23

    因为考试过多,所以学校的博客就暂时咕掉了,放到家里来写 不过话说,vscode的markdown编辑器还是真的很好用 先把 \(noip\) 模拟 \(23\) 的总结写了吧.. 俗话说:" ...

  9. NOIP 模拟 $34\; \rm Merchant$

    题解 \(by\;zj\varphi\) 对于选的物品,总值一定有在前一段区间递减,后一段递增的性质,那么就可以二分. check()时只递归归并大的一段,用nth_element即可 Code #i ...

  10. 「考试」noip模拟9,11,13

    9.1 辣鸡 可以把答案分成 每个矩形内部连线 和 矩形之间的连线 两部分 前半部分即为\(2(w-1)(h-1)\),后半部分可以模拟求(就是讨论四种相邻的情况) 如果\(n^2\)选择暴力模拟是有 ...

随机推荐

  1. Lattice高速下载器HW-USBN-2B 如何申请 license

    如果用的芯片不是停产老旧芯片,Diamond programmer 是不需要 license 绑定支持的. 但是有些需要编程老旧的芯片.需要安装 Diamond programmer stand-al ...

  2. CentOS+Django+uWSGI+Celery+Supervisor配置

    目录 背景 目录 安装 配置Supervisor 1.生成配置文件 2. 修改配置文件 3. 创建进程文件 创建 uwsgi.conf 进程文件 创建celery进程文件 启动supervisor 启 ...

  3. 力扣608(MySQL)-树节点(中等)

    题目: 给定一个表 tree,id 是树节点的编号, p_id 是它父节点的 id . 树中每个节点属于以下三种类型之一: 叶子:如果这个节点没有任何孩子节点.根:如果这个节点是整棵树的根,即没有父节 ...

  4. 阿里云张献涛:自主最强DPU神龙的秘诀

    ​简介:读懂云计算,才能看清DPU热潮. 微信公众号搜索"弹性计算百晓生",获取更多云计算知识. 如果细数最近火爆的科技概念,DPU必然位列其中. 这是英伟达一手捧红的新造富故事, ...

  5. 数据的“敏捷制造”,DataWorks一站式数据开发治理范式演进

    简介: 企业大数据技术发展至今,历经了两次蜕变.第一次蜕变从最初的"小作坊"解决大数据问题,到后来企业用各类大数据技术搭建起属于自己的"大平台",通过平台化的能 ...

  6. Go语言入门分享

    ​简介: Go语言出自Ken Thompson.Rob Pike和Robert Griesemer之手,起源于2007年,并在2009年正式对外发布.Go的主要目标是"兼具Python等动态 ...

  7. [Unreal] 虚拟现实理论与最佳实践

    优秀的虚拟现实场景所需要具备的特点: 真实感.沉浸感.舒适性.流畅性. VR的这些特点上有其它媒体所不具备的优势,主要通过硬件来实现. VR 的沉浸感让用户置身于周围世界,也引发了一些独特的症状: 眼 ...

  8. [FAQ] PHP Warning: json_encode(): double INF does not conform to the JSON spec

    如果待 json 编码元素的数值趋近无穷大,会有这个提示. 比如:小数位超出长度. 解决方式建议保留固定长度的位数,也可以四舍五入. round(sprintf('%.11f', xxxxx), 10 ...

  9. PostMan测试图片上传接口的方法

    一.选择POST后添加接口地址 二.选择Body下的from-data 注:Headers不要加参数 三.填写key,再key后的下拉选择file,然后选择文件 注:key并不是图片名称,而是接口接收 ...

  10. VSCode 在 windows 下默认添加 _WIN32 的问题

    现象 在 VSCode 在 windows 下环境中使用时,会默认添加 _WIN32 ,会出现查看代码时,出现错误提示,现象如下 检测到 #include 错误.请更新 includePath.已为此 ...