\(noip模拟27\;solutions\)

这次吧,我本来以为我能切掉两个题,结果呢??只切掉了一个

不过,隔壁Varuxn也以为能切两个,可惜了,他一个都没切。。。。。。

确实他分比我高一点,但是吧,这个人就改题非常慢,所以结论就是

我牛逼,牛逼到家了

所以我应该是挂掉了100pts,下次注意,下次AK

\(T1\;妹子图(graph)\)

这个题有一堆做法,而且旗鼓相当,复杂度都一样,跑的也差不多快

我的做法是在无向图上跑魔改拓扑排序+魔改DIJ,非常的恶心,但是吧,理解之后极其简单

按照堆优化的DIJ搞了一个优先队列,这样我们先把半仙的家能够连到的地方压到队列中

因为我们是按照边权小的在前面,所以我们当前找到的一定是当前困难抵抗值能够到达的最大的图

显然有一些困难抵抗值能够见到的妹子种类数是一样的,这些我们就不必保存了

这样的话,我们的数组里最多只有2e5个点,直接保证了时间和空间复杂度

我们开始弹队列,然后更新这个数组,这里面存的东西就是

能够看到当前这么多妹子的最小困难抵抗值,和能够看到的妹子

最后的时候直接在这个数组里二分查找,搞一搞边界就好了

复杂度是\(O(nlogn+qlogn)\)

AC_code

#include<bits/stdc++.h>
using namespace std;
#define re register int
#define ll long long
const int N=5e5+5;
int n,m,qq,hom,opt,mod;
int c[N];
ll num[N],fro[N],bas[N],cnt;
int to[N*2],nxt[N*2],val[N*2],head[N],rp;
void add_edg(int x,int y,int z){
to[++rp]=y;
val[rp]=z;
nxt[rp]=head[x];
head[x]=rp;
}
int ton[N],sum;
bool vis[N];
struct node{
int val,tag;
node(){}
node(int x,int y){
val=x;tag=y;
}
bool operator < (node x)const{
return val>x.val;
}
};
priority_queue<node> q;
signed main(){
scanf("%d%d%d%d%d",&n,&m,&qq,&hom,&opt);
if(opt)scanf("%d",&mod);
for(re i=1;i<=n;i++){
scanf("%d",&c[i]);
}
for(re i=1,x,y,z;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
add_edg(x,y,z);
add_edg(y,x,z);
}
ton[c[hom]]++;sum++;
for(re i=head[hom];i;i=nxt[i])
q.push(node(val[i],to[i]));
int cge=0;bas[++cnt]=1;num[cnt]=sum;
while(!q.empty()){
int dis=q.top().val;
int now=q.top().tag;
q.pop();
if(vis[now])continue;
vis[now]=true;
cge=max(cge,dis);
ton[c[now]]++;
if(ton[c[now]]==1){
sum++;
if(bas[cnt]!=cge)
bas[++cnt]=cge;
num[cnt]=sum;
}
for(re i=head[now];i;i=nxt[i]){
q.push(node(val[i],to[i]));
}
}
bas[++cnt]=1e9+1;
for(re i=1;i<=cnt;i++){
fro[i]=fro[i-1]+1ll*num[i-1]*(bas[i]-bas[i-1]);
//cout<<bas[i]<<" "<<num[i]<<" "<<fro[i]<<endl;
}
ll lans=0;
for(re i=1;i<=qq;i++){
ll x,y;
scanf("%lld%lld",&x,&y);
if(opt==1){
x=(x^lans)%mod+1;
y=(y^lans)%mod+1;
}
if(x>y)swap(x,y);
int ld=upper_bound(bas+1,bas+cnt+1,x)-bas;
int rd=upper_bound(bas+1,bas+cnt+1,y)-bas-1;
//cout<<ld<<" "<<rd<<" "<<num[ld]<<" "<<bas[ld]<<endl;
ll ans=fro[rd]-fro[ld];
ans+=1ll*(bas[ld]-x)*num[ld-1];
ans+=1ll*(y-bas[rd]+1)*num[rd];
printf("%lld\n",ans);
lans=ans;
}
}


\(T2\;妹子腿(tree)\)

真是没想到啊,没想到,这个竟然是个大暴力,主要是他还能过,气死人,比线段树还快

考场上没敢写,气人。

就是维护被标记的点的标记时间以及和要查询的点的距离,

这个距离就是树剖+LCA,完事!!!

注意优化,要不然过不了,如果要标记的点已经在不断的扩散中被标记了,就不要加进去了。

AC_code

#include<bits/stdc++.h>
using namespace std;
#define re register int
#define fi first
#define se second
#define pa pair<int,int>
#define mpa(x,y) make_pair(x,y)
const int N=1e5+5;
int n,m;
int to[N*2],nxt[N*2],head[N],rp;
void add_edg(int x,int y){
to[++rp]=y;
nxt[rp]=head[x];
head[x]=rp;
}
int fa[N],dep[N];
int siz[N],son[N],top[N];
void dfs1(int x){
siz[x]=1;son[x]=0;
for(re i=head[x];i;i=nxt[i]){
int y=to[i];
if(y==fa[x])continue;
fa[y]=x;dep[y]=dep[x]+1;
dfs1(y);
siz[x]+=siz[y];
if(!son[x]||siz[y]>siz[son[x]])son[x]=y;
}
}
void dfs2(int x,int f){
top[x]=f;
if(son[x])dfs2(son[x],f);
for(re i=head[x];i;i=nxt[i]){
int y=to[i];
if(y==fa[x]||y==son[x])continue;
dfs2(y,y);
}
}
int LCA(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=fa[top[x]];
}
return dep[x]<dep[y]?x:y;
}
int DIS(int x,int y){
return dep[x]+dep[y]-2*dep[LCA(x,y)];
}
pa ji[N];
int cnt;
signed main(){
scanf("%d%d",&n,&m);
for(re i=1,x,y;i<n;i++){
scanf("%d%d",&x,&y);
add_edg(x,y);add_edg(y,x);
}
dfs1(1);dfs2(1,1);
for(re i=1,typ,x;i<=m;i++){
scanf("%d%d",&typ,&x);
if(typ==1){
int flag=0;
for(re j=1;j<=cnt;j++){
if(DIS(ji[j].fi,x)<=i-ji[j].se){
flag=1;break;
}
}
if(flag==1)continue;
ji[++cnt]=mpa(x,i);
}
if(typ==2)cnt=0;
if(typ==3){
int flag=0;
for(re j=1;j<=cnt;j++){
if(DIS(ji[j].fi,x)<=i-ji[j].se){
flag=1;break;
}
}
if(flag==1)printf("wrxcsd\n");
else printf("orzFsYo\n");
}
}
}


\(T3\;妹子腰(序列)\)

这个题我一眼就是原题,而且是昨天的原题

后来发现不对,是极长上升而不是最长上升

所以我忘记了如何维护这个东西了,考完试又去回顾了一下,好难哟!!!

就是一个\(O(log^2n)\)的线段树,注意维护一个底线,来保证是极长的。。

AC_code

#include<bits/stdc++.h>
using namespace std;
#define re register int
#define ll long long
const int N=2e5+5;
const ll inf=0x3f3f3f3f3f3f3f3f;
const ll mod=998244353;
int n,a[N],maxd;
struct node{
#define ls x<<1
#define rs x<<1|1
ll sum[N*4];
int mxra[N*4];
ll work(int x,int l,int r,int maxn){
//cout<<x<<" "<<l<<" "<<r<<endl;
if(l==r){
if(mxra[x]>maxn)return sum[x];
return 0;
}
int mid=l+r>>1;
if(maxn>mxra[x])return 0;
else if(maxn>mxra[rs])return work(ls,l,mid,maxn);
else{
ll ret=0;
ret=(ret+work(rs,mid+1,r,maxn))%mod;
ret=(ret+work(ls,l,mid,mxra[rs]))%mod;
return ret;
}
}
void pushup(int x){
mxra[x]=max(mxra[ls],mxra[rs]);
//sum[x]=(sum[ls]+sum[rs])%mod;
return ;
}
void ins(int x,int l,int r,int pos,int mx,int v){
if(l==r){
mxra[x]=mx;
sum[x]=v;
return ;
}
int mid=l+r>>1;
if(pos<=mid)ins(ls,l,mid,pos,mx,v);
else ins(rs,mid+1,r,pos,mx,v);
pushup(x);return ;
}
ll query(int x,int l,int r,int pos){
if(pos==0)return 0;
if(r<=pos){
ll ret=work(x,l,r,maxd);
maxd=max(maxd,mxra[x]);
return ret;
}
int mid=l+r>>1;ll ret=0;
if(pos>mid)ret=(ret+query(rs,mid+1,r,pos))%mod;
ret=(ret+query(ls,l,mid,pos))%mod;
return ret;
}
#undef ls
#undef rs
}xds;
ll ans,dp[N];
signed main(){
scanf("%d",&n);
for(re i=1;i<=n;i++)scanf("%d",&a[i]);
for(re i=1;i<=n;i++){
maxd=0;
dp[i]=xds.query(1,1,n,a[i]-1);
//cout<<dp[i]<<" ";
if(dp[i]==0)dp[i]=1;
xds.ins(1,1,n,a[i],i,dp[i]);
//cout<<dp[i]<<endl;
}
int mx=0;
for(re i=n;i>=1;i--){
if(a[i]>mx)ans=(ans+dp[i])%mod,mx=a[i];
}
printf("%lld",ans);
}


noip模拟27[妹子图·腿·腰](fengwu半仙的妹子们)的更多相关文章

  1. 2021.7.29考试总结[NOIP模拟27]

    T1 牛半仙的妹子图 做法挺多的,可以最小生成树或者最短路,复杂度O(cq),c是颜色数. 我考场上想到了原来做过的一道题影子,就用了并查集,把边权排序后一个个插入,记录权值的前缀和,复杂度mlogm ...

  2. 7.29考试总结(NOIP模拟27)[牛半仙的妹子图·Tree·序列]

    前言 从思路上来讲是比较成功的,从分数上就比较令人失望了. 考场上是想到了前两个题的正解思路,其实最后一个题是半个原题,只可惜是我看不懂题... 这波呀,这波又是 语文素养限制OI水平.. 改题的时候 ...

  3. NOIP 模拟 $27\; \rm 牛半仙的妹子序列$

    题解 \(by\;zj\varphi\) 明显一道极长上升子序列的题. 直接线段树维护单调栈,最后单调栈求出可以贡献的序列,答案相加就行. Code #include<bits/stdc++.h ...

  4. NOIP 模拟 $27\; \rm 牛半仙的妹子Tree$

    题解 \(by\;zj\varphi\) 很妙的虚树题. 考虑若没有操作 \(2\),那么直接记录一下扩散到它的最短时间和询问时间相比即可,可以当作一个树上最短路. 有 \(2\) 操作怎么办,将操作 ...

  5. NOIP模拟赛 混合图

    [题目描述] Hzwer神犇最近又征服了一个国家,然后接下来却也遇见了一个难题. Hzwer的国家有n个点,m条边,而作为国王,他十分喜欢游览自己的国家.他一般会从任意一个点出发,随便找边走,沿途欣赏 ...

  6. 20190820 Tue 集训总结&NOIP模拟 27

    低谷度过了? 但是skyh阿卡了,还是反衬出我的辣鸡. T1知道要sort,却忘了判重,正解不如暴力分高,555. T2成功化出正解柿子,然后化过头了,化出了无法DP的柿子. 果然不够强,大神们一眼就 ...

  7. NOIP模拟27

    两个机房又和在一起考试 开场看了看T1,感觉挺水的,过. T2,这个式子有点奇怪,暂时没什么思路,过 T3,好像保留最后几位换个根处理一下就行了,过,先去打T1 于是T1大概打了0.5h,连暴力带正解 ...

  8. NOIP模拟27(命悬一线)

    考得太悬了!

  9. NOIP 模拟 $27\; \rm 牛半仙的妹子图$

    题解 \(by\;zj\varphi\) 颜色数很少,考虑枚举颜色数. 建出来一棵最小生成树,可以证明在最小生成树上,一个点到另一个点的路径上的最大权值最小(易证,考虑 \(\rm kruskal\) ...

随机推荐

  1. WebClient (史上最全)

    疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 面试必备 + 面试必备 [博客园总入口 ] 疯狂创客圈 经典图书 : <Sprin ...

  2. Linkerd 2.10(Step by Step)—将 GitOps 与 Linkerd 和 Argo CD 结合使用

    Linkerd 2.10 系列 快速上手 Linkerd v2.10 Service Mesh(服务网格) 腾讯云 K8S 集群实战 Service Mesh-Linkerd2 & Traef ...

  3. 【题解】Luogu P3110 [USACO14DEC]驮运Piggy Back

    [题解]Luogu P3110 [USACO14DEC]驮运Piggy Back 题目描述 Bessie and her sister Elsie graze in different fields ...

  4. AliCloudDenoise 语音增强算法:助力实时会议系统进入超清音质时代

    近些年,随着实时通信技术的发展,在线会议逐渐成为人们工作中不可或缺的重要办公工具,据不完全统计,线上会议中约有 75% 为纯语音会议,即无需开启摄像头和屏幕共享功能,此时会议中的语音质量和清晰度对线上 ...

  5. AJAX异步原理与实现

    面试时问到了这个问题,说实话我还是不理解的,只是单单会使用.所以今天我看一下,自己了解下. 看了网上前辈们写的资料,我自己总结归纳ajax的原理和流程如下: 1.AJAX创建异步对象XMLHttpRe ...

  6. LCD1602液晶显示模块的单片机驱动深入详解之软件篇(AVR)

    LCD1602液晶显示模块的驱动虽然比七段数码管之类的显示要复杂一些,但实际上也并不是很难,最主要的还是初始化,为什么这么说呢?我们在调试一块新液晶屏的时候,都会先初始化看看有没有光标在闪,没有光标前 ...

  7. Java实现工厂模式

    工厂模式(Factory),当需要根据运行时的一些条件来决定创建具体对象时,就应该考虑使用工厂设计模式,将创建对象的任务交给工厂集中处理. 工厂模式有多种写法,总体分为简单工厂模式和抽象工厂模式 工厂 ...

  8. excel VBA中Xldown和xlup用法

    1.Worksheets("Sheet1").Range("A1").End(xlDown).Select     '意思为自A1起,返回从上往下的最后一个非空 ...

  9. 3、mysql的多实例配置(3)

    8.mysql多实例故障排错:

  10. Docker与k8s的恩怨情仇(四)-云原生时代的闭源落幕

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 在本系列前几篇文章中,我们介绍了从Cloud Foundry到Docker等PaaS平台的发展迭代过程.今天 ...