csps-s模拟测试62,63Graph,Permutation,Tree,Game题解
题面:https://www.cnblogs.com/Juve/articles/11631298.html
permutation:
参考:https://www.cnblogs.com/clno1/p/10832579.html
因为原来的数组不好做于是我们想反过来数组,根据交换条件:值相邻且位置差大于等于k,那么在变换后的数组就变成了位置相邻且差值大于等于k。这样的话变换操作变成了,相邻的大于等于k的值临近交换,于是我们注意到因为现在只能临近交换的原因,两个差值小于k的数他们的相对位置不可能发生改变。那么问题就变成了,在只有一些相对位置限制条件下,无限制的可以随意交换位置,求这个数组的最小字典序(原数组字典序最小也是现在数组字典序最小)。那么我们容易想到拓扑排序。
但是如果每个点都想后面差值小于k的点连边的话,这个图会变得十分巨大,时间无法承受。于是我们必循得考虑优化建图:我们注意到像a->b,b->c,a->c这种建图,a->c这条边是不必要的。于是我们想办法避免掉这种无意义的边,所以对于某个点,我们让它向后面的所有限制(即差值小于k)中只向最小的那一个点连边,那么用线段树维护这样的信息,这样就达到优化建图的目的。
这样只向最小的连边为什么是对的呢?借用上面大佬的一句话:倒着加入,显然 p_i 连向 (p_i-k, p_i)∪(p_i, p_i+k)。我们只需要分别连向两个区间中下标最小的那一个即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int MAXN=5e5+;
int n,k,a[MAXN],pos[MAXN],du[MAXN],ans[MAXN],num=;
vector<int>m[MAXN];
priority_queue<int>q;
int tr[MAXN<<];
void update(int k,int l,int r,int opt,int val){
if(l==r){
tr[k]=min(tr[k],val);
return ;
}
int mid=(l+r)>>;
if(opt<=mid) update(k<<,l,mid,opt,val);
else update(k<<|,mid+,r,opt,val);
tr[k]=min(tr[k<<],tr[k<<|]);
}
int query(int k,int l,int r,int opl,int opr){
if(opl>opr) return 0x3f3f3f3f;
if(opl<=l&&r<=opr) return tr[k];
int mid=(l+r)>>,res=0x3f3f3f3f;
if(opl<=mid) res=min(res,query(k<<,l,mid,opl,opr));
if(opr>mid) res=min(res,query(k<<|,mid+,r,opl,opr));
return res;
}
int main(){
scanf("%d%d",&n,&k);
for(int i=;i<=n;++i){
scanf("%d",&a[i]);
pos[a[i]]=i;
}
memset(tr,0x3f,sizeof(tr));
for(int i=n;i>=;--i){
int p=query(,,n,max(,pos[i]-k+),pos[i]);
if(p<=n) m[pos[i]].push_back(pos[p]),++du[pos[p]];
p=query(,,n,pos[i],min(n,pos[i]+k-));
if(p<=n) m[pos[i]].push_back(pos[p]),++du[pos[p]];
update(,,n,pos[i],i);
}
for(int i=;i<=n;++i){
if(!du[i]) q.push(-i);
}
while(!q.empty()){
int x=-q.top();
q.pop();
ans[x]=++num;
int N=m[x].size();
for(int i=;i<N;++i){
int y=m[x][i];
--du[y];
if(!du[y]) q.push(-y);
}
}
for(int i=;i<=n;++i){
printf("%d\n",ans[i]);
}
return ;
}
tree:
好像是个结论:边权之和就是答案
#include<cstdio>
#define int long long
int n,ans=;
signed main(){
scanf("%lld",&n);
for(int i=,u,v,w;i<n;++i){
scanf("%lld%lld%lld",&u,&v,&w);
ans+=w;
}
printf("%lld\n",ans);
return ;
}
game:
模拟用堆可以有50分
考虑如何优化
我们对于前p个数找出最大值,并开桶统计所有数出现的次数
然后对于一个新加入的点,如果它大于当前的最大值,那么下一个人一定选择新加如的这个点,所以最大值没有变
否则更新新加入的数的次数并更新最大值
考虑到最大值一定不上升,所以复杂度较有保障
但是还是会T,所以我们离散化一下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<unordered_map>
#define re register
using namespace std;
const int MAXN=;
int n,k,a[MAXN],p,tim[MAXN],cnt,b[MAXN];
signed main(){
scanf("%d%d",&n,&k);
for(re int i=;i<=n;++i) scanf("%d",&a[i]),b[i]=a[i];
sort(b+,b+n+);
cnt=unique(b+,b+n+)-b-;
for(int i=;i<=n;++i) a[i]=lower_bound(b+,b+cnt+,a[i])-b;
while(k--){
scanf("%d",&p);
re long long ans1=,ans2=;
re int maxp=;
for(re int i=;i<=p;++i){
++tim[a[i]];
maxp=max(maxp,a[i]);
}
ans1+=b[maxp];
--tim[maxp];
while(maxp>&&tim[maxp]==) --maxp;
for(re int i=;i<=n;++i){
if(i&){
if(p+<=n){
++p;
if(a[p]>=maxp) ans1+=b[a[p]];
else{
ans1+=b[maxp];
--tim[maxp];
++tim[a[p]];
while(maxp>&&tim[maxp]==) --maxp;
}
}else{
ans1+=b[maxp];
--tim[maxp];
while(maxp>&&tim[maxp]==) --maxp;
}
}else{
if(p+<=n){
++p;
if(a[p]>=maxp) ans2+=b[a[p]];
else{
ans2+=b[maxp];
--tim[maxp];
++tim[a[p]];
while(maxp>&&tim[maxp]==) --maxp;
}
}else{
ans2+=b[maxp];
--tim[maxp];
while(maxp>&&tim[maxp]==) --maxp;
}
}
}
printf("%lld\n",ans1-ans2);
}
return ;
}
csps-s模拟测试62,63Graph,Permutation,Tree,Game题解的更多相关文章
- [CSP-S模拟测试62]题解
A.Graph 因为点可以随便走,所以对于每个联通块,答案为边数/2向下取整. 用类似Tarjan的方式,对于每个联通块建立一棵搜索树,尽量让每一个节点的儿子两两配对,如果做不到就用上头顶的天线. # ...
- [考试反思]1006csp-s模拟测试62:隔断
本来说好的好一场烂一场. 那样的日子结束了,连着烂了两场...幸亏T3傻逼了救我一命不算太惨... T1树上的特殊性质会做但是没有继续想下去就死在错贪心上了还没有过那个点... T2迭代至稳定被我错误 ...
- csp-s模拟测试61砖块, 数字,甜圈题解
题面:https://www.cnblogs.com/Juve/articles/11626350.html 砖块: 直接模拟即可,map统计被覆盖的次数 #include<iostream&g ...
- csp-s模拟测试56Merchant, Equation,Rectangle题解
题面:https://www.cnblogs.com/Juve/articles/11619002.html merchant: 二分答案,贪心选前m大的 但是用sort复杂度不优,会T掉 我们只是找 ...
- csp-s模拟测试54x,y,z题解
题面:https://www.cnblogs.com/Juve/articles/11606834.html x: 并差集,把不能分到两个集合里的元素和并到一起,设连通块个数为cnt,则答案为:$2^ ...
- csp-s模拟测试53u,v,w题解
题面:https://www.cnblogs.com/Juve/articles/11602450.html u: 用差分优化修改 二维差分:给(x1,y1),(x2,y2)加上s: $d[x1][y ...
- 2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色
2019.8.3 [HZOI]NOIP模拟测试12 B. 数颜色 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 数据结构学傻的做法: 对每种颜色开动态开点线段树直接维 ...
- csp-s模拟测试99
csp-s模拟测试99 九九归一直接爆炸. $T1$一眼板子. $T2$一眼语文题(语文的唯一一次$120+$是给模拟出来的可知我的语文能力). $T3$一眼普及题. ?? Hours Later 板 ...
- csp-s模拟测试98
csp-s模拟测试98 $T1$??不是我吹我轻松手玩20*20.$T2$装鸭好像挺可做?$T3$性质数据挺多提示很明显? $One$ $Hour$ $Later$ 这$T1$什么傻逼题真$jb$难调 ...
随机推荐
- (转)poi操作Excel, 各种具体操作和解释
原文地址http://hi.baidu.com/j_changhong/item/981fa58d05fa755926ebd96b注原文是3.6 此文是3.9 java读取excel文件的顺序是: E ...
- PAT_A1053#Path of Equal Weight
Source: PAT A1053 Path of Equal Weight (30 分) Description: Given a non-empty tree with root R, and w ...
- .net与C#
一..net包含什么? 1.包含庞大的代码库,分为多个模块,可以自主选择 2.定义了基本的类型,被称为通用类型系统(CTS,common type system): 3.包含.NET公共语言运行库(C ...
- webpack3
6月20号webpack推出了3.0版本,官方也发布了公告.根据公告介绍,webpack团队将未来版本的改动聚焦在社区提出的功能需求,同时将保持一个快速.稳定的发布节奏.本文主要依据公告内容,简单介绍 ...
- 如何使用Hive集成Solr?
(一)Hive+Solr简介 Hive作为Hadoop生态系统里面离线的数据仓库,可以非常方便的使用SQL的方式来离线分析海量的历史数据,并根据分析的结果,来干一些其他的事情,如报表统计查询等. So ...
- 安装keepalived 出现configure: error: Popt libraries is required
keepalived执行./configure --prefix=/usr/local/keepalived时报错:configure: error: Popt libraries is requir ...
- 检测到“RuntimeLibrary”的不匹配项
- CSIC_716_20191108【文件的操作,以及彻底解决编码问题的方案】
关于编码的问题: 在平时编写代码,涉及到打开文件时,常常遇到字符编码的报错, 通过总结,得出以下规律 如果在操作过程中涉及到调用文本文档,一定要在文本文档开头申明编码方式(# coding:XXXX ...
- ubuntu下安装git提示无root权限
apt-get install git 获取git指令 sudo passwd root 重置unix密码 su root 键入密码 参考链接 https://www.cnblogs.com/2she ...
- Flask框架图