Problem A

  • 思路

这是一道带权并查集问题

因为只有三种种类,我们分别用0,1,2来表示,即0-->1,1-->2,2-->0。

我们需要知道x和y的关系,即需知道x和祖先xx的关系,y和祖先yy的关系,即可得x和y的关系。

①当x的祖先和y的祖先不同时,可知x和y的关系在前面并没有体现,所以此话一定是真的

②当x的祖先和y的祖先相同时,通过x,y和祖先的关系可知x所在种类和y所在种类的关系,即可判断话的真假

  • AC代码
#include <iostream>
#include <cstdio>
using namespace std;
#define ll long long
ll n,k,p,x,y,ans;
ll f[50005],val[50005];
int found(ll x)
{
if(x==f[x])return x;
ll temp=found(f[x]);
val[x]=(val[x]+val[f[x]])%3;
return f[x]=temp;
}
int fun(ll d,ll x,ll y)
{
ll xx=found(x);
ll yy=found(y);
if(xx!=yy)
{
f[yy]=xx;
val[yy]=(val[x]-val[y]+d+3)%3;
return 0;
}
else
{
if((val[y]-val[x]+3)%3==d)return 0;
else return 1;
}
}
int main()
{
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n;i++)f[i]=i;
while(k--)
{
scanf("%lld%lld%lld",&p,&x,&y);
if(x>n||y>n||(p==2&&x==y)){++ans;continue;}
if(fun(p-1,x,y))++ans;
}
printf("%lld\n",ans);
return 0;
}

Problem B

  • 思路

此题是一个思维题,里面有用到线段树的知识

因为是从1开始变到p,所以数组中必然要有p出现。

其中所有的0都要变为非0且小于等于q的数字,我们只需要把0变为左边相邻的数字即可,注意第一个数字为0时的情况

然后记录所有数字出现的最小和最大位置,即可得到一个区域,在此区域若出现比其小的数字,则不可能。

  • AC代码
#include <iostream>
#include <cstdio>
using namespace std;
#define ll long long
const int INF=0x3f3f3f3f;
int n,q,a[200005],st[1000000],g=0,b[200005][2];
void build(int root,int l,int r)
{
if(l==r)st[root]=a[l];
else
{
int mid=(l+r)>>1;
build(root<<1,l,mid);
build((root<<1)+1,mid+1,r);
st[root]=min(st[root<<1],st[(root<<1)+1]);
}
}
int query(int root,int l,int r,int s,int e)
{
if(l>e||r<s)return INF;
if(s<=l&&e>=r)return st[root];
int mid=(l+r)>>1;
return min(query(root<<1,l,mid,s,e),query((root<<1)+1,mid+1,r,s,e));
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cin>>n>>q;
for(int i=1;i<=n;i++)cin>>a[i];
//判断是否有最大的数字
for(int i=1;i<=n;i++)
if(a[i]==q){g=1;break;}
//将所有的0变成非0数字,保证数组里要有最大的数字
int l=0;
if(!g)
{
for(l=l+1;l<=n;l++)
if(!a[l]){a[l]=q;break;}
if(l>n){cout<<"NO"<<endl;return 0;}
}
else if(!a[1])
{
for(l=2;l<=n;l++)
if(a[l])break;
for(int i=1;i<l;i++)
a[i]=a[l];
}
for(;l<=n;l++)if(!a[l])a[l]=a[l-1];
//记录数字出现的最小的位置和最大的位置
for(int i=1;i<=n;i++)
{
if(!b[a[i]][0])b[a[i]][0]=i;
b[a[i]][1]=i;
}
build(1,1,n);
//判断此数字出现的区间里是否有比它小的数字出现
for(int i=1;i<=q;i++)
{
if(!b[i][0])continue;
if(query(1,1,n,b[i][0],b[i][1])<i)
{
cout<<"NO"<<endl;
return 0;
}
}
cout<<"YES"<<endl;
for(int i=1;i<=n;i++)cout<<a[i]<<" ";
cout<<endl;
return 0;
}

Problem C

  • 思路

这题最难绕的就是“左子树+右子树”并不等于总的,因为它update的时候右子树是特殊计算的。还是因为在这个最长上升序列的问题中虽然计算单个区间的时候是不考虑左右影响的,但是update的时候为了正确得到这个区间的结果,右子树还是要考虑左子树的影响的,这是造成val[i<<1]+val[(i<<1)+1]≠≠val[i]的原因。

  • AC代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,val[500010];
double Max[500010];
bool dlt[500010];
int divide(int i,int l,int r,double v){
if (l==r) return Max[i]>v;
int mid=(l+r)>>1;
if (Max[i]<=v) return 0;
if (Max[i<<1]<=v) return divide((i<<1)+1,mid+1,r,v);
else return val[i]-val[i<<1]+divide(i<<1,l,mid,v);
}
void change(int i,int l,int r,int x,double v){
if (l==r){
Max[i]=v;val[i]=1;
return;
}
int mid=(l+r)>>1;
if (x<=mid) change(i<<1,l,mid,x,v);
else change((i<<1)+1,mid+1,r,x,v);
Max[i]=max(Max[i<<1],Max[(i<<1)+1]);
val[i]=val[i<<1]+divide((i<<1)+1,mid+1,r,Max[i<<1]);
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++){
int x,y;scanf("%d%d",&x,&y);
double v=(double)y/(double)x;
change(1,1,n,x,v);
printf("%d\n",val[1]);
}
return 0;
}

Problem D

  • 思路

dp+最短路

令f[i]为到第i天的最少成本,那么显然有f[i]=min(f[i],f[j]+cost(j+1,i)+k),其中cost(i,j)为i天到j天的最小花费,然后直接最短路搞

  • AC代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 205;
vector<pair<int,int> >e[maxn];
int d[maxn];
int vis[maxn];
int unreach[maxn][maxn];
int f[maxn];
int n,m,k,ee;
int dijkstra(int s,int t)
{
memset(vis,0,sizeof(vis));
for(int i = s;i<=t;i++)
for(int j = 1;j<=m;j++)
{
if(unreach[j][i])
vis[j]=1;
}
for(int i = 1;i<=m;i++)
d[i]=9999999;
queue<int>q;
d[1]=0;
q.push(1);
// vis[1]=1;
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i = 0;i<e[u].size();i++)
{
int v= e[u][i].first;
if(vis[v])
continue;
if(d[v]>d[u]+e[u][i].second)
{
d[v]=d[u]+e[u][i].second;
//vis[v]=1;
q.push(v);
}
}
} return d[m]*(t-s+1);
}
int main()
{
scanf("%d%d%d%d",&n,&m,&k,&ee);
for(int i = 0;i<ee;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
e[u].push_back(make_pair(v,w));
e[v].push_back(make_pair(u,w));
}
int q;
scanf("%d",&q);
while(q--)
{
int u,a,b;
scanf("%d%d%d",&u,&a,&b);
for(int i = a;i<=b;i++)
unreach[u][i]=1;
}
for(int i = 1;i<=n;i++)
{
f[i]=dijkstra(1,i);
for(int j = 2;j<i;j++)
{
f[i]=min(f[i],f[j]+dijkstra(j+1,i)+k);
}
}
printf("%d\n",f[n]);
}

Problem E

此题来自某位学长的友情赞助,是给你们的签到题

  • 思路

先把数组a全部赋值为-1,表示数组的这个数未分组。然后一个个数字扫进来,如果这个数字没有分组的话,我们找到这个组的范围max(0,p-k+1)~p,如果前面的最小数字未分组或者分组的情况使它自己的话,我们就从前面最小的数字到p分组为最小的数字。

  • AC代码
#include <iostream>
#include <cstdio>
using namespace std;
#define ll long long
const int INF=0x3f3f3f3f;
int main()
{
int a[257],n,k;
for (int i = 0; i < 257; i++) a[i] = -1;
scanf("%d %d", &n, &k);
for (int i = 0; i < n; i++)
{
int p;
scanf("%d", &p);
if (a[p] == -1)
{
for (int j = max(0, p - k + 1); j <= p; j++)
{
if (a[j] == -1 || a[j] == j)
{
for (int k = j; k <= p; k++)
a[k] = j;
break;
}
}
}
printf("%d", a[p]);
if (i != n - 1) printf(" ");
else printf("\n");
}
return 0;
}

Problem F

  • 思路

二分一下边权。然后跑最小生成树判断即可。

  • AC代码
#include<iostream>
#include<cstdio>
#define N 10010
using namespace std;
struct use{int st,en,v1,v2;}e[N*3];
int n,ans,cnt,l,r,m,k,x,y,v,w,fa[N];
int find(int x){if (x!=fa[x]) fa[x]=find(fa[x]);return fa[x];}
bool check(int x){
int temp(0);
for (int i=1;i<=n;i++) fa[i]=i;
for (int i=1;i<=cnt;i++)
if (e[i].v1<=x){
int r1=find(e[i].st),r2=find(e[i].en);
if (r1!=r2){fa[r1]=r2;temp++;}
}
if (temp<k) return false;
for (int i=1;i<=cnt;i++)
if (e[i].v2<=x){
int r1=find(e[i].st),r2=find(e[i].en);
if (r1!=r2){fa[r1]=r2;temp++;}
}
if (temp!=n-1) return false;
return true;
}
int main(){
scanf("%d%d%d",&n,&k,&m);
for (int i=1;i<=m;i++){
scanf("%d%d%d%d",&x,&y,&v,&w);
e[++cnt].st=x;e[cnt].en=y;e[cnt].v1=v;e[cnt].v2=w;
}
l=1;r=30000;
while(l<=r){
int mid=(l+r)>>1;
if (check(mid)) r=mid-1;
else l=mid+1;
}
cout<<l<<endl;
}

2018HUAS_ACM暑假比赛5题解的更多相关文章

  1. FJUT2019暑假周赛一题解

    A.排队问题*-* 题意就是有长度为L的序列,每位的取值可以是'f'或者'm',问不包含'fff'和'fmf'的个数. 打表找规律 不难找出递推公式为F[n] = F[n-1] + F[n-3] + ...

  2. 【codeforces】【比赛题解】#868 CF Round #438 (Div.1+Div.2)

    这次是Div.1+Div.2,所以有7题. 因为时间较早,而且正好赶上训练,所以机房开黑做. 然而我们都只做了3题.:(. 链接. [A]声控解锁 题意: Arkady的宠物狗Mu-mu有一只手机.它 ...

  3. 纪中OJ 2019.02.15【NOIP提高组】模拟 B 组 梦回三国 比赛题解(第一个)

    声明 旁边的同学小 H(胡)对我说: “哟,比赛拿了 140,强!要知道,如果哥第三题 AC 了,哥就 230 了,你个废柴!!!(比赛实际分数 130 额呵)” 顿时,千万草泥马从我心中奔腾而过:你 ...

  4. ECJTUACM16 Winter vacation training #4 题解&源码

    A......................................................................................... 题目链接→Code ...

  5. Nowcoder | [题解-N189]牛客OI赛制测试赛3

    这场说实话确实水(逃*1),表示差一点就AK了(逃*2),然而被卡两个特判的我\(ssfd\)...\(qwq\) 表示这是第一次发整场比赛的题解...还请各位大佬原谅我太蒻写的垃圾啊\(qwq\). ...

  6. 年少和 Smart の日常比赛 R3

    在洛谷上参加了个比赛....写写题解 rank3....共5人...(捂脸 没有注明是官方代码的均是我比赛时本人提交的代码 T1  洗牌 题目描述 小明把 n (n 为偶数)张牌按编号顺序 1, 2, ...

  7. Codeforces Round #469 Div. 2题解

    A. Left-handers, Right-handers and Ambidexters time limit per test 1 second memory limit per test 25 ...

  8. Codeforces Round #382 Div. 2【数论】

    C. Tennis Championship(递推,斐波那契) 题意:n个人比赛,淘汰制,要求进行比赛双方的胜场数之差小于等于1.问冠军最多能打多少场比赛.题解:因为n太大,感觉是个构造.写写小数据, ...

  9. CH Round #58 - OrzCC杯noip模拟赛day2

    A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...

随机推荐

  1. SpringCloud实战 | 第三篇:SpringCloud整合Nacos实现配置中心

    前言 随着eureka的停止更新,如果同时实现注册中心和配置中心需要SpringCloud Eureka和SpringCloud Config两个组件;配置修改刷新时需要SpringCloud Bus ...

  2. 安装Scrapy提示ERROR: 'xslt-config' 不是内部或外部命令,也不是可运行的程序

    环境:win7.Python 2.7.12.PyCharm 2016.3 Requirement already satisfied (use --upgrade to upgrade): scrap ...

  3. DVWA sql注入low级别

    DVWA sql注入low级别 sql注入分类 数字型注入 SELECT first_name, last_name FROM users WHERE user_id = $id 字符型注入 SELE ...

  4. Linux实战(9):Docker一键搭建kms服务

    server端 docker pull luodaoyi/kms-server docker run -itd -p 1688:1688 --name kms luodaoyi/kms-server ...

  5. 虚拟机系列 | JVM特点,基础结构与执行周期

    本文源码:GitHub·点这里 || GitEE·点这里 一.虚拟机简介 1.虚拟机概念 虚拟机(Virtual Machine)指通过软件模拟的具有完整硬件系统功能的.运行在一个完全隔离环境中的完整 ...

  6. session深入探讨

    简介 session(会话),其实是一个容易让人误解的词.它总跟web系统的会话挂钩,利用session,javaweb项目实现了登录状态的控制.坊间流传,关闭浏览器,就是关闭了web系统的会话. 其 ...

  7. Bottleneck靶机渗透

    Bottleneck 端口扫描,主机发现. 敏感目录为:http://192.168.114.165/image_gallery.php 在该目录下发现:http://192.168.114.165/ ...

  8. Depthwise Separable Convolution(深度可分离卷积)的实现方式

    按照普通卷积-深度卷积-深度可分离卷积的思路总结. depthwise_conv2d来源于深度可分离卷积,如下论文: Xception: Deep Learning with Depthwise Se ...

  9. # js权威指南之对象篇

    对象是js中的关键 属性查找 in,Object.hasOwnProperty(),Object.propertyIsEnumerable()都能检测出对象内是否存在某个属性 in关键字 自有属性/继 ...

  10. P3431 [POI2005]AUT-The Bus

    Link 简化题意: 给你一张网格图,每个点有其对应的权值,让你找出来一条横纵坐标都单调不降的路径,并最大化经过点的权值. 分析: 这是经典的二维数点或者二维偏序问题. 如果两维一直在变的话,我们不是 ...