题目比较神仙,注意是题目神仙

贪婪暗示贪心,堆积暗示堆优化$\%\%\%\%\%\%\%$

两个乱搞$+$一个堆优化$dp$

嚎叫响彻在贪婪的机房

题解

对于一个序列来说只要他们差的$gcd$不为$1$就可以构成等差数列

例如

$2$    $4$     $16$

$2$与$4$差$2$ $4$与$16$差$12$

$gcd(2,12)!=1$故构成等差序列

那么我们维护公差,然后每次的差和当前公差比较,若$gcd==1$则等差数列从这里断开,否则将公差置成$gcd$

举个例子

$2$     $8$    $14$      $16$     $18$      $20$

$2$     $8$    $14$构成公差为$6$等差数列,之后$16$     $18$      $20$构成公差为$2$等差序列

显然我们可以让他们合并为公差为$2$等差序列

注意判重,判差为$1$,

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define A 1111111
ll read(){ll x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f;
}
set<ll> st;
set<ll> ::iterator it;
ll n,m,d=0,ans=0;
ll a[A];
void  cl(ll x){st.clear();d=0;ans++;st.insert(a[x]);
}
ll gcd(ll x,ll y){if(y==0) return x;return gcd(y,x%y);
}
int main(){n=read();for(ll i=1;i<=n;i++){a[i]=read();}cl(1);for(ll i=2;i<=n;i++){if((it=st.find(a[i]))!=st.end()) {
//        printf("i=-%lld\n",i);
            cl(i);continue;}if(abs(a[i]-a[i-1])==1||a[i]==a[i-1]){cl(i);continue;}
//        printf("d=%lld\n",d);if(d==0){st.insert(a[i]);d=abs(a[i]-a[i-1]);}else {ll g=gcd(d,abs(a[i]-a[i-1]));
//            printf("g=%lld d=%lld abs=%lld\n",g,d,abs(a[i]-a[i-1]));if(g==1||g==0){cl(i);}else {st.insert(a[i]);d=g;}}}printf("%lld\n",ans);
}

View Code

主仆见证了 Hobo 的离别

题解

建边,建立包含关系的树,例如$1,2$交集为$3$那么$1$包含$3$,$2$包含$3$

再例如$1,2$并集为$3$那么$3$包含$1$,$3$包含$2$

询问$x$,$y$所属关系就从$y$开始$dfs$若找到$x$即符合

暴力就是正解

让我们分析一下复杂度

题目中说

新元件的编号等于融合之前元件的总个数加一。当然,参与融合的 K个元件融合之后依然存在,并且每个元件至多参与一次融合

数据范围

极限情况下肯定就是分开连边

那么$250000$个分开连边,产生$125000$,然后下一层产生$62500$再下一层.....

显然是$log$的最终是$18$层

而且我们建出来树是下图这样的从一点往下搜

所以极限复杂度$18*250000$可过

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define A 1111111
ll read(){ll x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f;
}
ll n,m,cnt,ok,tot=0;
ll some[A],fa[A],nxt[A],ver[A],head[A];
ll find(ll x){if(fa[x]!=x){fa[x]=find(fa[x]);}return fa[x];
}
void haha(){for(ll i=1;i<=500000;i++){fa[i]=i;}
}
void merge(ll x,ll y){x=find(x),y=find(y);if(x!=y) fa[x]=y;
}
void add(ll x,ll y){
//    printf("x=%lld y=%lld\n",x,y);nxt[++tot]=head[x],head[x]=tot,ver[tot]=y;
}
void dfs(ll x,ll pre,ll ineed){if(x==ineed) ok=1;if(ok) return ;for(ll i=head[x];i;i=nxt[i]){ll y=ver[i];if(y==pre) continue;dfs(y,x,ineed);}
}
/*ll ithave[A],beihave[A];
ll getithave(ll x){if(ithave[x]!=x){ithave[x]=getithave(ithave[x]);}return ithave[x];
}
void mergeit(ll x,ll y){x=getithave(x);y=getithave(y);if(ithave[x]!=ithave[y]){ithave[x]=y;}
}
ll getbeihave(ll x){if(beihave[x]!=x){beihave[x]=getbeihave(beihave[x]);}return beihave[x];
}
void mergebei(ll x,ll y){x=getbeihave(x);y=getbeihave(y);if(beihave[x]!=beihave[y]){beihave[x]=y;}
}*/
int main(){n=read(),m=read();cnt=n;for(ll i=1,opt,ques,k,QwQ;i<=m;i++){ques=read();if(ques==0){opt=read(),k=read();cnt++;if(opt==1){for(ll j=1;j<=k;j++){QwQ=read();//1属于2 1--->2
                    add(cnt,QwQ);if(k==1)add(QwQ,cnt);}}else {for(ll j=1;j<=k;j++){QwQ=read();add(QwQ,cnt);if(k==1)add(cnt,QwQ);}}}else{ok=0;ques=read(),QwQ=read();dfs(QwQ,0,ques);printf("%lld\n",ok);}}
}

View Code

征途堆积出友情的永恒

题解

首先普通dp应该都会吧

$f[i]=min(f[j]+max(sum[i]-sum[j],b[j]))$

    for(ll i=1;i<=n;i++){for(ll j=max(i-k,0ll);j<=i-1;j++){ll fee=max(sum[i]-sum[j],a[j]);f[i]=min(f[j]+fee,f[i]);}}

一言不和上代码

怎么优化,

线段树或者堆

思考sum[i]变化很烦,线段树很难维护(然而Mr_zkt维护出来了$%%%$)我没打线段树

用堆维护我们需要寻找不变量显然$f[j]+b[j]$和$f[j]-sum[j]$是不变量

开两个小根堆,一个维护$min(f[j]+b[j])$一个维护$f[j]-sum[j]$

转移时$min(q1.top(),q2.top+sum[i])$

细节稍多

  • $STL$的各种$empty$往上仍,
  • 判断是否可以转移(<=k)限制
  • 在$f[j]+b[j]$$<$$f[j]-sum[j]+sum[i]$时第一个堆不合法,第一个堆扔到第二个堆

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define A 1010101
ll f[A],a[A],sum[A],b[A];
ll n,k,minn;
struct node{ll id,val;friend bool operator < (const node &a,const node &b){return a.val>b.val;}
};
priority_queue<node> q1,q2;
//q1用来存f+b q2存 f-s
ll read(){ll x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=x*10+(c-'0');c=getchar();}return f*x;
}
void work(){memset(f,0x3f,sizeof(f));f[0]=0;node o;o.id=0,o.val=b[0];q1.push(o);for(ll i=1;i<=n;i++){node x1,x2;while(!q1.empty()){x1=q1.top();if(x1.id>=i-k) break;q1.pop();}while(!q2.empty()){x2=q2.top();if(x2.id>=i-k) break;q2.pop();}while(!q1.empty()){x1=q1.top();if(x1.val>=f[x1.id]-sum[x1.id]+sum[i]) break;
//            printf("feifa\n");
//            printf("x1.val=%lld id=%lld f-s=%lld\n",x1.val,x1.id,f[x1.id]-sum[x1.id]+sum[i]);
            q1.pop();node x3;x3.id=x1.id,x3.val=f[x1.id]-sum[x1.id];q2.push(x3);}while(!q1.empty()){x1=q1.top();if(x1.id>=i-k) break;q1.pop();}while(!q2.empty()){x2=q2.top();if(x2.id>=i-k) break;q2.pop();}
//        printf("q1.top id=%lld val=%lld 2=%lld %lld\n",x1.id,x1.val,x2.id,x2.val);//f[i]=min(x1.val,x2.val+sum[i]);if(!q1.empty())f[i]=min(0x7ffffffffff,q1.top().val);if(!q2.empty())f[i]=min(0x7ffffffffff,q2.top().val+sum[i]);
//        printf("f[%lld]=%lld\n",i,f[i]);x1.id=i,x1.val=f[i]+b[i];q1.push(x1);}
}
int main(){n=read(),k=read();for(ll i=1;i<=n;i++){sum[i]=read();sum[i]+=sum[i-1];}for(ll i=0;i<n;i++){b[i]=read();}work();printf("%lld\n",f[n]);
}

View Code

转载于:https://www.cnblogs.com/znsbc-13/p/11377871.html

NOIP模拟测试26「嚎叫响彻在贪婪的机房·主仆见证了 Hobo 的离别·征途堆积出友情的永恒」...相关推荐

  1. 8.19 NOIP模拟测试26(B) 嚎叫响彻在贪婪的厂房+主仆见证了 Hobo 的离别+征途堆积出友情的永恒...

    T1 嚎叫响彻在贪婪的厂房 以前做过一个等比数列的题「序列」,这个类似 是等差数列且公差不为1的条件就是各项差的绝对值的$gcd!=1$,每次拿出序列前两个数,求出差值,插入到set里,每次向后扩展, ...

  2. 征途堆积出友情的永恒「堆优化dp」

    直接写题解: 很简单的dp暴力转移式子:f[i]=MAX{f[j]+max(tax[j],sum[i]-sum[j])} 观察式子,只有一个变量sum[i]; 而其他都为定量; 则考虑维护 两个定量: ...

  3. NOIP模拟测试19「count·dinner·chess」

    反思: 我考得最炸的一次 怎么说呢?简单的两个题0分,稍难(我还不敢说难,肯定又有人喷我)42分 前10分钟看T1,不会,觉得不可做,完全不可做,把它跳了 最后10分钟看T1,发现一个有点用的性质,仍 ...

  4. NOIP模拟测试30「return·one·magic」

    magic 题解 首先原式指数肯定会爆$long$ $long$ 首先根据欧拉定理我们可以将原式换成$N^{\sum\limits_{i=1}^{i<=N} [gcd(i,N)==1] C_{G ...

  5. NOIP模拟测试21「折纸·不等式」

    折纸 题解 考试时无限接近正解,然而最终也只是接近而已了 考虑模拟会爆炸,拿手折纸条试一试,很简单 考你动手能力 代码 #include<bits/stdc++.h> using name ...

  6. NOIP模拟测试18「引子·可爱宝贝精灵·相互再归的鹅妈妈」

    待补 引子 题解 大模拟,注意细节 代码1 #include<bits/stdc++.h> using namespace std; int n,m;char a[1005][1005]; ...

  7. NOIP模拟测试11「string·matrix·big」

    打的big出了点小问题,maxx初值我设的0然后少了10分 第二题暴力打炸 第一题剪了一些没用的枝依然40分 总分70 这是一次失败的考试 string 想到和序列那个题很像,但我没做序列,考场回忆学 ...

  8. NOIP模拟测试10「大佬·辣鸡·模板」

    大佬 显然假期望 我奇思妙想出了一个式子$f[i]=f[i-1]+\sum\limits_{j=1}^{j<=m} C_{k \times j}^{k}\times w[j]$ 然后一想不对得容 ...

  9. NOIP模拟测试38「金·斯诺·赤」

    金 辗转相减见祖宗 高精 #include<bits/stdc++.h> using namespace std; #define A 2000 #define P 1 #define N ...

最新文章

  1. Flutter Dart 安装在window系统
  2. python Series 添加行_傻傻分不清系列 | Python中各种字符串处理方法
  3. Html5 dragdrop
  4. 2017(深圳) .NET技术分享交流会 第二期,将有网络直播
  5. YBTOJ洛谷P4298:祭祀(二分图匹配)
  6. mongodb使用指南
  7. Bootstrap按钮组中按钮的尺寸
  8. c mysql dll_PHP5.3以上版本没有libmysql.dll,以及由此带来的困扰
  9. 关于Adobe AIR 获取屏幕信息及任务栏高度.
  10. 微信企业号支付个人php实现
  11. ThinkPHP5集成JS-SDK实现微信自定义分享功能
  12. JmeterTCP返回响应码500
  13. 百度地图-根据地址获取经纬度
  14. go语言入门(转载自开源社区)
  15. java实现12306查票_GitHub - HendSame/J12306: 12306抢票程序JAVA版
  16. 《测量助理》最新版本V3.0.221215发布更新
  17. 操作Python列表Ⅰ
  18. A Deep Learning-Based Remaining Useful Life Prediction Approach for Bearings 基于深度学习的轴承剩余寿命预测
  19. 2018任天堂服务器维护,任天堂更改Switch网络收费政策,并延迟至2018年
  20. CF375C Circling Round Treasures(BFS+DP)

热门文章

  1. 安全审计报告_企业做税审的五大好处!税审报告和审计报告的区别
  2. Servlet规范中定义的过滤器
  3. 正则表达式的贪婪模式、非贪婪模式、占有模式
  4. Sublime Text for Windows的快捷键
  5. fanuc roboguide_FANUC机器人虚拟仿真教程:Roboguide弧焊仿真工作站工装添加
  6. c语言实现两个有序链表的合并(代码示例)
  7. 【lua学习】3.字符串
  8. 网络营销理论模型_网络营销:课堂笔记(第四章下)
  9. php键盘输入函数,php的常用输入语句以及常用函数
  10. pycharm如何更改python项目环境_PyCharm如何导入python项目,并配置虚拟环境