https://www.zhixincode.com/contest/7/problems

A题

分类讨论

当B有点需要经过时 穿梭的花费肯定为2*k,也可以发现,我们要找到包含所有需要经过的点(不含起点)的最小矩形,端点肯定是传送门,排序,找到需要经过最小的值和最大的值,再分别找小于等于和大于等于他们的传送门, 作为矩形端点,再判断起点的位置,最终得出答案。

当B无点需要经过时 分三种考虑,起点在最左边,最右边,在中间,很容易想到。

#include<bits/stdc++.h>
#define all(a) (a).begin(),(a).end()
using namespace std;
typedef unsigned long long ull;
const int maxn=2e6+;
int n,r,m,k,s;
int main()
{
scanf("%d%d%d%d%d",&n,&r,&m,&k,&s);
vector<int> x,y,zhuan{,n};
for(int i=;i<r;i++)
{
int a,b;
scanf("%d%d",&a,&b);
if(a==s&&b==)
continue;
if(b==)
x.push_back(a);
else
y.push_back(a);
}
sort(all(x));sort(all(y));
while(m--)
{
int c;
scanf("%d",&c);
zhuan.push_back(c);
}
sort(all(zhuan));
if(y.size()>)
{
int l,r;
if(x.size()==)
r=*(--y.end()),l=*y.begin();
else
{
r=max(*(--x.end()),*(--y.end()));
l=min(*x.begin(),*y.begin());
}
int ans1=zhuan[upper_bound(all(zhuan),l)-zhuan.begin()-];
int ans2=zhuan[lower_bound(all(zhuan),r)-zhuan.begin()];
int ans=(ans2-ans1+k)*;
if(s<ans1)
ans+=(ans1-s)*;
else if(s>ans2)
ans+=(s-ans2)*;
cout<<ans<<endl;
return ;
}
x.push_back(s);
sort(all(x));
if(x.size()==&&*x.begin()==s)
cout<<<<endl;
else if(*x.begin()==s)
{
int ans=zhuan[lower_bound(all(zhuan),*(--x.end()))-zhuan.begin()];
cout<<(ans-s)*<<endl;
}
else if(*(--x.end())==s)
{
int ans=zhuan[upper_bound(all(zhuan),*x.begin())-zhuan.begin()-];
cout<<(s-ans)*<<endl;
}
else
{
int ans1=zhuan[upper_bound(all(zhuan),*x.begin())-zhuan.begin()-];
int ans2=zhuan[lower_bound(all(zhuan),*(--x.end()))-zhuan.begin()];
cout<<(ans2-ans1)*<<endl;
}
}
//20 4 2 50 4
//7 0
//13 0
//15 1
//6 1
//5
//

B

dp dp[x][y][k]表示 第k秒 x,y 获得的最大值,初始化dp[xs][ys][0]=0其他数组为-inf 若干秒后 dp[x][y][k]>0 肯定是由起点转移过来的。

枚举时间找到满足的最小时间就好了。

#include<bits/stdc++.h>
#define all(a) (a).begin(),(a).end()
using namespace std;
typedef unsigned long long ull;
const int maxn=;
int mp[][],dp[][][maxn];
int main()
{
int n,m,C,xs,xt,ys,yt;
scanf("%d%d%d",&n,&m,&C);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
scanf("%d",&mp[i][j]);
scanf("%d%d%d%d",&xs,&ys,&xt,&yt);
memset(dp,-0x3f,sizeof(dp));
dp[xs][ys][]=;
for(int k=;k<maxn;k++)
{
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
dp[i][j][k]=max({dp[i-][j][k-],dp[i][j+][k-],dp[i+][j][k-],dp[i][j-][k-],dp[i][j][k-]})+(k%mp[i][j]==?:);
}
}
}
int ans=-;
for(int i=;i<maxn;i++)
{
if(dp[xt][yt][i]>=C)
{
ans=i;
break;
}
}
printf("%d\n",ans); }

C 不会证,但是猜到了。。。

E

树形dp dp[x][0]表示不选x,dp[x][1]表示选择x,根据题意写状态转移方程就好了

#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
#define huan printf("\n")
#define debug(a,b) cout<<a<<" "<<b<<" "<<endl
#define ffread(a) fastIO::read(a)
using namespace std;
typedef long long ll;
const int maxn = 1e5+;
const int maxm = 1e4+;
const int inf = 0x3f3f3f3f;
const ll mod = ;
const double epx = 1e-;
const double pi = acos(-1.0);
//head------------------------------------------------------------------
struct edge
{
int to,next;
}e[maxn];
int head[maxn],tot;
int dp[maxn][],vis[maxn],f[maxn],d[maxn],n;
void init()
{
tot=;
fillchar(head,-);
fillchar(vis,);
}
void add(int u,int v)
{
e[tot].to=v;
e[tot].next=head[u];
head[u]=tot++;
}
void dfs(int x,int y)
{
vis[x]=;
dp[x][]=;
dp[x][]=f[x];
for(int i=head[x];i!=-;i=e[i].next)
{
int v=e[i].to;
if(v==y)
continue;
dfs(v,x);
dp[x][]+=max(dp[v][],dp[v][]);
dp[x][]+=max(dp[v][],dp[v][]-d[min(x,v)]);
}
}
int main()
{
init();
cin>>n;
for(int i=;i<=n;i++)
cin>>f[i];
for(int i=;i<=n;i++)
cin>>d[i];
for(int i=;i<=n;i++)
{
if(i%==)
add(i/,i),add(i,i/);
else if(*i+<=n)
add(*i+,i),add(i,*i+);
}
int ans=;
for(int i=;i<=n;i++)
if(!vis[i])
{
dfs(i,-);
ans+=max(dp[i][],dp[i][]);
}
cout<<ans<<endl;
}

F最短路

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii; const double PI=acos(-1.0);
const double eps=1e-;
const ll mod=1e9+;
const int inf=0x3f3f3f3f;
const int maxn=1e5+;
const int maxm=+;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); int n,m,k;
int cnt=,head[maxn<<];
bool vist[maxn];
ll dis[maxn],body[maxn];
priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > >q; struct node{
int v,nex;
ll w;
}edge[maxn<<]; void add(int u,int v,ll w)
{
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].nex=head[u];
head[u]=cnt++;
} void dijkstra(int s)
{
dis[s]=;//到自己的最短距离直接设为0
q.push(make_pair(,s));
while(!q.empty()){//队列非空
int u=q.top().second;q.pop();
vist[u]=true;
for(int i=head[u];~i;i=edge[i].nex){
int v=edge[i].v;
ll w=edge[i].w+(body[v]>k?(body[v]-k)*(body[v]-k):);
if(dis[v]>dis[u]+w){//满足条件更新距离
dis[v]=dis[u]+w;
//p[v]=u;//保存路径
q.push(make_pair(dis[v],v));//把更新完的值压入队列
}
}
}
} int main()
{
memset(head,-,sizeof(head));//初始化数组
memset(vist,false,sizeof(vist));
//memset(dis,inf,sizeof(dis));
cin>>n>>m>>k;
for(int i=;i<=n;i++)
dis[i]=1e18;
for(int i=;i<=n;i++)
cin>>body[i];
for(int i=;i<=m;i++){
int u,v;ll w;
cin>>u>>v>>w;
add(u,v,w);
add(v,u,w);//无向图相互可达 有向图一次就好
}
k+=body[];
dijkstra();
cout<<dis[n]<<endl;

I  树状数组+dfs

解析 长度肯定是奇数3,5,7,9...然后会发现 长度5的是两个长度3的连起来,长度7的是三个长度3的连起来...

那我们就先来找长度为3的序列 枚举左右端点l r, 由于每个数的大小不超过2000,所以我们开2000个树状数组来记录小于j的个数

所以就有 if(a[l]>a[r])   我们getsum(a[r],r)-getsum(a[r],l)得到(l,r) 区间中小于a[r]的个数k,然后 l - ->r 连一条有向边权值为k

复杂度O(n*n*log(n))

图建完之后dfs计数dp[i] 表示以i为起点的路径总数 从叶子向上递归。

1-->5-->10-->15 这条链的过程就是 dp[15]=0,dp[10]=dp[15]*2+2,dp[5]=dp[10]*4+4,dp[1]=dp[5]*3+3

枚举起点,采用记忆化来降低复杂度,O(n)。

这个解法不是最好的,其他大佬代码又短又快QAQ。

#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(a) (a).begin(), (a).end()
#define fillchar(a, x) memset(a, x, sizeof(a))
#define huan printf("\n")
#define debug(a,b) cout<<a<<" "<<b<<" "<<endl
#define ffread(a) fastIO::read(a)
using namespace std;
typedef long long ll;
const int maxn = 2e3+;
const int inf = 0x3f3f3f3f;
const ll mod = ;
const double epx = 1e-;
const double pi = acos(-1.0);
//head------------------------------------------------------------------
int a[maxn],c[maxn][maxn],tot,n,head[maxn],vis[maxn];
ll dp[maxn]; //对应原数组和树状数组
int lowbit(int x){
return x&(-x);
}
void updata(int j,int i,int k)
{
while(i <= n){
c[j][i] += k;
i += lowbit(i);
}
}
int getsum(int j,int i)
{ //求A[1 - i]的和
int res = ;
while(i > ){
res += c[j][i];
i -= lowbit(i);
}
return res;
}
struct edge
{
int to,val,next;
}e[maxn*maxn];
void add(int u,int v,int w)
{
e[tot].val=w;
e[tot].to=v;
e[tot].next=head[u];
head[u]=tot++;
}
void init()
{
tot=;
memset(head,-,sizeof(head));
memset(vis,,sizeof(vis));
}
void dfs(int x)
{
if(vis[x])
return;
for(int i=head[x];i!=-;i=e[i].next)
{
ll v=e[i].to,w=e[i].val;
dfs(v);
dp[x]=(dp[x]+dp[v]*w%mod+w)%mod;
}
vis[x]=;
}
int main()
{
init();
//freopen("C:\\Users\\HP\\Desktop\\a.txt","r",stdin);
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
for(int j=a[i]+;j<=n;j++)
updata(j,i,);
}
for(int i=;i<=n;i++)
{
for(int j=i+;j<=n;j++)
{
if(a[i]<a[j])continue;
int temp=getsum(a[j],j)-getsum(a[j],i);
if(temp)
add(a[i],a[j],temp);
}
}
ll ans=;
for(int i=;i<=n;i++)
{
dfs(a[i]);
ans=(ans+dp[a[i]])%mod;
}
printf("%lld\n",ans);
}

J 这题应该是cf原题了 做法是枚举答案。

CCPC-Wannafly Winter Camp Day1 (Div2, online mirror) A,B,C,E,F,I,J的更多相关文章

  1. 2020 CCPC Wannafly Winter Camp Day1 C. 染色图

    2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...

  2. Comet OJ CCPC-Wannafly Winter Camp Day1 (Div2, online mirror) F.爬爬爬山-最短路(Dijkstra)(两个板子)+思维(mdzz...) zhixincode

    爬爬爬山 已经提交 已经通过 9.83% Total Submission:417 Total Accepted:41 题目描述 爬山是wlswls最喜欢的活动之一. 在一个神奇的世界里,一共有nn座 ...

  3. 2020 CCPC Wannafly Winter Camp Day1 Div.1&amp F

    #include<bits/stdc++.h> #define forn(i, n) for (int i = 0; i < int(n); i++) #define fore(i, ...

  4. 2020 CCPC Wannafly Winter Camp Day1 - I. K小数查询(分块)

    题目链接:K小数查询 题意:给你一个长度为$n$序列$A$,有$m$个操作,操作分为两种: 输入$x,y,c$,表示对$i\in[x,y] $,令$A_{i}=min(A_{i},c)$ 输入$x,y ...

  5. CCPC-Wannafly Winter Camp Day1 (Div2 ABCFJ) 待补...

    Day1 Div2 场外链接 按题目顺序~ A 机器人 传送门 题意:有两条平行直线A.B,每条直线上有n个点,编号为1~n.在同一直线上,从a站点到b站点耗时为两点间的距离.存在m个特殊站点,只有在 ...

  6. CCPC Wannafly Winter Camp Div2 部分题解

    Day 1, Div 2, Prob. B - 吃豆豆 题目大意 wls有一个\(n\)行\(m\)列的棋盘,对于第\(i\)行第\(j\)列的格子,每过\(T[i][j]\)秒会在上面出现一个糖果, ...

  7. 2019 CCPC-Wannafly Winter Camp Day1 (Div2, onsite)

    solve:4/11 补题:6/11 A 机器人 补题:zz 这是一道分类讨论的题目,有一个规律就是如果必须要从第一个区到第二个区,那么最多转区两次(1到2一次,2到1一次),然后分类讨论即可,只要细 ...

  8. CCPC-Wannafly Winter Camp Day1 (Div2, onsite) A B C E F I J

    A 机器人 链接:https://www.cometoj.com/contest/7/problem/A?problem_id=92 思路: 分两大类讨论: 1. B区没有点: (1)点都在起点左边 ...

  9. CCPC-Wannafly Winter Camp Day1 (Div2, onsite)

    Replay Dup4: 要是不挂机,再多仔细想想就好了 J确实自闭好久,一直在想正确性,最后数据错了,喵喵喵? 还是要保证充足的休息啊,中间睡了一小会儿,也不知道睡了多久,醒来他们就又过了一道 要发 ...

随机推荐

  1. C语言中函数参数传递

    C语言中函数参数传递的三种方式 (1)值传递,就是把你的变量的值传递给函数的形式参数,实际就是用变量的值来新生成一个形式参数,因而在函数里对形参的改变不会影响到函数外的变量的值.(2)地址传递,就是把 ...

  2. 企业自颁布服务器证书的有效性验证(C#为例)

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/notjusttech/article/details/72779904 目前根据项目的需要,整理了一 ...

  3. PAT (Advanced Level) Practise - 1098. Insertion or Heap Sort (25)

    http://www.patest.cn/contests/pat-a-practise/1098 According to Wikipedia: Insertion sort iterates, c ...

  4. 当数据量很少的时候,tableview会显示多余的cell--iOS开发系列---项目中成长的知识二

    当数据量很少的时候,tableview会显示很多的cell,而且是空白的,这样很不美观 所以使用下面的方法可以去掉多余的底部的cell 原理是:设置footerView为frame 是 CGRectZ ...

  5. sha1、base64、ase加密

    <!DOCTYPE html><html><head><title>sha1.base64.ase加密</title><meta ch ...

  6. Luogu P1080国王游戏(贪心)

    国王游戏 题目链接:国王游戏 ps:题目数据说明了要写高精度. 这个题的答案是\(a.l * a.r < b.l * b.r\)按照这个进行排序 题解中大部分只是如何证明排序是: \(a.l * ...

  7. netfilter 和 iptables

    http://blog.chinaunix.net/uid/23069658/cid--1-list-4.html 洞悉linux下的Netfilter&iptables  系列,有一到十六, ...

  8. History Api以及hash操作

    https://segmentfault.com/a/1190000002447556#articleHeader12 https://developer.mozilla.org/zh-CN/docs ...

  9. 【php】关于尾部去除和分号问题

    One thing to remember is, if you decide to omit the closing PHP tag, then the last line of the file ...

  10. Solr5.0.0 DIH之增量索引

    定时索引相关知识 增量更新需要配置个sql(deltaImportQuery.deltaQuery) deltaImportQuery="select * where id='${dih.d ...