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. 关于swagger

    转自https://blog.csdn.net/sanyaoxu_2/article/details/80555328 1:认识Swagger Swagger 是一个规范和完整的框架,用于生成.描述. ...

  2. OOCSS是什么,该如何用?

    1 OOCSS的定义: Object Oriented css(面向对象css)的缩写,是一种用最简单的方式编写的CSS代码,从而使代码 重用性,可维护性和可扩展性更好的书写方法.   2 OOCSS ...

  3. 003.当在windows终端输入ipconfig时,显示不是内部或外部命令,也不是可运行的程序或批处理文件

    当在windows终端输入ipconfig时,显示不是内部或外部命令,也不是可运行的程序或批处理文件,这是环境变量的问题: 右键我的电脑→→→属性→→→高级系统设置→→→(高级)环境变量 在弹出的窗口 ...

  4. SpringBoot-03-配置之yaml语法学习

    3. SpringBoot配置 3.1 yaml语法学习 配置文件 Springboot使用一个全局的配置文件,配置文件名称固定 spplication.properties 语法结构:key=val ...

  5. php bypass disable function

    前言 最近开学,事太多了,好久没更新了,然后稍微闲一点一直在弄这个php bypass disable function,一开始自己的电脑win10安装蚁剑的插件,一直报错.怀疑是必须linux环境. ...

  6. PHP正则表达式核心技术完全详解 第2节

    作者:极客小俊 一个专注于web技术的80后 我不用拼过聪明人,我只需要拼过那些懒人 我就一定会超越大部分人! CSDN@极客小俊,原创文章, B站技术分享 B站视频 : Bilibili.com 个 ...

  7. 推荐一个超牛的SpringCloud微服务项目,开发脚手架

    前言 Cloud-Platform是国内首个基于Spring Cloud微服务化开发平台,具有统一授权.认证后台管理系统,其中包含具备用户管理.资源权限管理.网关API 管理等多个模块,支持多业务系统 ...

  8. VueX中state变化捕捉不到_getters监测不到state的变化

    原因 可能有多种原因, 现在我说一下我碰到的一种情况: state种有一个变量叫state,它是一个json对象, 可把我害惨了.因为他这个json长这个样: messageBox:{ friendI ...

  9. 程序员的开源月刊:HelloGitHub(第 54 期)

    兴趣是最好的老师,HelloGitHub 就是帮你找到兴趣! 简介 分享 GitHub 上有趣.入门级的开源项目. 这是一个面向编程新手.热爱编程.对开源社区感兴趣 人群的月刊,月刊的内容包括:各种编 ...

  10. Java知识系统回顾整理01基础07类和对象01引用

    一.引用的定义 引用的概念,如果一个变量的类型是 类类型,而非基本类型,那么该变量又叫做引用. 二.引用和指向 new Hero(); 代表创建了一个Hero对象 但是也仅仅是创建了一个对象,没有办法 ...