slz的题 KCN

雨中的晴天

宫水三叶生活的城市是一个一维平面上的城市。三叶喜欢用一个长度为n的线段来表示这座城市。线段上(包含端点)平均分布着 $n+1$ 个点,其中第 $i$ 个点到第 $i+1$ 个点视为第 $i$ 个区。

最近,这座城市不断的下雨,一直没有放晴,所有人都在期待的晴天。不同的区对晴天的渴望度不一样。三叶通过统计,将第 $i$ 个区的人对晴天的渴望度形式化成 $s_i$ 。

终于,这座城市迎来了久违的晴天。但是晴天的范围没有覆盖整个城市,而是从 $n+1$ 个点中的某一个出发,向往扩散 $d$ 个区。

在晴天下的人们非常开心。形式化的,如果第 $i$ 个区在晴天的覆盖范围内,并且和晴天中心还隔着 $x$ 个区,那么这个区的人的开心值为 $(d-x)^2 \cdot s_i$ 。这个城市的开心值为每一个区的开心值之和。

虽然晴天的地点已经固定了,但是三叶还是想知道如果晴天的地点可以任选,那么最后城市的开心值最大是多少?

sol

有两段,可以分开考虑

每一段形如$  s_i \times 1+s_{i+1} \times 4+s_{i+2} \times 9+...+s_{i+d-1} \times d^2 $

往前移动时,更新的值与原来的值差形如 $ \sum 2 \times (i+x) \times s_i$ x为常数

预处理维护即可。

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 2000006
#define _(d) while(d(isdigit(ch=getchar())))
#define ll long long
using namespace std;
ll n,s[maxn],d;
ll sum[maxn],s1[maxn],s2[maxn],a1,a2,ans,S,T;
ll R(){
ll v,f=;char ch;_(!)if(ch=='-')f=-;
v=(ch^);_()v=(v<<)+(v<<)+(ch^);
return v*f;
}
int main()
{
n=R();d=R();
for(ll i=d+;i<=d+n;i++)s[i]=R();
n=n+d+d;
for(ll i=;i<=n;i++)sum[i]=sum[i-]+s[i],s1[i]=s1[i-]+1LL*i*s[i];
for(ll i=n;i>=;i--)s2[i]=s2[i+]+1LL*(n-i+)*s[i];
for(ll i=;i<=d;i++)a1+=s[i]*i*i;
for(ll i=d+,j=d;i<=d+d;i++,j--)a2+=s[i]*j*j;
ans=max(ans,a1+a2);
for(ll i=;i<=n-d-d;i++){
ll m=i+d-;
a1=a1-s[i-]+s[m]*d*d;
S=sum[m-]-sum[i-];
T=(s1[m-]-s1[i-])-(i-)*S;
a1=a1-S-*T; a2=a2-s[m]*d*d+s[m+d];
S=sum[m+d-]-sum[m];
T=(s2[m+]-s2[m+d])-S*(n-m-d+);
a2=a2+S+*T;
ans=max(ans,a1+a2);
}
cout<<ans<<endl;
return ;
}

燃烧的火焰

宫水三叶擅长手工,她自己编织了一张网。

这张网可以用一个 $n$ 个点 $m$ 条边的连通图来表示,每一条边都有长度。

但是这张网毕竟是可燃物。某一天,网上的 $k$ 个节点在 $0$ 时刻突然同时被点燃了,火焰以单位速度沿着边向外扩散。具体来说,如果有一条长度为 $l$ 的边连接着点 $x,y$ ,假设第 $i$个 时刻 $x$ 节点被点燃了,那么在 $i+l$ 的时刻 $y$ 节点也会被点燃。反之也是成立的。

如果整张图的 $n$ 个节点全部被点燃了,那么就认为这张图完全被点燃了。

既然着火了,那么首要任务就是救火。三叶请小`H`来帮忙。在 $0$ 时刻时,小`H`随机选择了若干个已经被点燃的点,将它们扑灭。但是,小`H`扑灭了那些点后并没有使整张图完全被点燃的时间推晚!

三叶觉得小`H`运气太差了,于是她想知道这个事件的概率。

形式化的说,小`H`有 $2^k$ 种灭火方案(包含一个都不选)。假设小`H`随机从中选一种,有多少概率选到的灭火方案没能使整张图完全被点燃的时间推晚。

假设在没有灭火时整张图完全被点燃从时刻 $a$ 开始,灭火后整张图完全被点燃从时刻 $b$ 开始,而没能使整张图完全被点燃的时间推晚的方案当且仅当 $a=b$ 。

sol

多源最短路求出每一个点到任意一个着火点的最短距离,即为该点被点燃的时间。

记所有被点燃的最晚时间为Max

考虑一个非法方案,该方案一定会把到某点距离小于等于Max的着火点全部扑灭。

那么可以得到点集S,S的所有超集都是非法方案。

考虑dp f[S]|=f[S-(1<<i)]

效率2^n*n+nlogn

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define maxn 100005
#define inf 1e16
#define ll long long
#define mod 998244353
using namespace std;
int n,m,num,s[],f[<<],head[maxn],tot;
int flag[maxn];
ll d[maxn],dis[maxn][],M[maxn],Max,ans;
struct node{
int v,w,nex;
}e[maxn*];
struct no{
int x;ll dist;
};
bool operator <(no A,no B){return A.dist>B.dist;}
void add(int t1,int t2,int t3){
e[++tot].v=t2;e[tot].w=t3;e[tot].nex=head[t1];head[t1]=tot;
}
void dij(int S,int id){
priority_queue<no>q;
for(int i=;i<=n;i++)d[i]=inf,flag[i]=;
q.push((no){S,});d[S]=;
while(!q.empty()){
no k=q.top();q.pop();
if(flag[k.x])continue;
flag[k.x]=;
for(int i=head[k.x];i;i=e[i].nex){
if(d[e[i].v]>d[k.x]+e[i].w){
d[e[i].v]=d[k.x]+e[i].w;
q.push((no){e[i].v,d[e[i].v]});
}
}
}
for(int i=;i<=n;i++)dis[i][id]=d[i],M[i]=min(M[i],d[i]);
}
ll work(ll a,ll N){
ll A=;for(;N;N>>=,a=a*a%mod)if(N&)A=A*a%mod;return A;
}
int main()
{
scanf("%d%d%d",&n,&m,&num);
for(int i=;i<=num;i++)scanf("%d",&s[i]);
for(int i=,t1,t2,t3;i<=m;i++){
scanf("%d%d%d",&t1,&t2,&t3);
add(t1,t2,t3);add(t2,t1,t3);
}
for(int i=;i<=n;i++)M[i]=inf;
for(int i=;i<=num;i++)dij(s[i],i);
for(int i=;i<=n;i++)Max=max(Max,M[i]);
int Al=(<<num)-;
for(int i=;i<=n;i++){
int t=;
for(int j=;j<=num;j++){
if(dis[i][j]<=Max)t|=(<<(j-));
}
int S=(Al^t);
f[S]=;
}
for(int i=Al;i;i--){
for(int j=;j<=num;j++){
f[i]|=f[i|(<<(j-))];
}
}
for(int i=;i<=Al;i++)ans+=f[i];
ans++;
ll A=work(work(,num),mod-);
ans=ans*A%mod;ans=(-ans+mod)%mod; printf("%lld\n",ans);
return ;
}

contest20191023的更多相关文章

随机推荐

  1. linux IPC socket(3)server简单写法

    写server的一些流程总结 一.向内核申请一个socket TCP形式 sock_fd = socket(AF_INET, SOCK_STREAM, ); UDP形式 sfd = socket(AF ...

  2. ZROI week6

    ZROI week6 T1 用一个类似背包的东西记录答案. T2 好像直接用|操作即可. T3 瞎搞就完事了 T4 启发式合并,然而变量写错了,就没了... 总结 100 + 100 + 100 + ...

  3. for循环中执行setTimeout问题(任务队列的问题)

    for(var i=0;i<8;i++){ setTimeout(function () { console.log(i) },0) } 输出了8次8,这跟js的执行顺序和作用域链有关. 规则: ...

  4. CMDB 调研报告

    基础概念 1.什么是CMDB CMDB——配置管理数据库,通过识别.控制.维护,检查企业的IT资源,从而高效控制与管理不断变化的IT基础架构与IT服务,并为其它流程,例如事故管理.问题管理.变更管理. ...

  5. java 并发——volatile

    java 并发--volatile 介绍 维基百科: volatile 是一个类型修饰符(type specifier).volatile 的作用是确保本条指令不会因编译器的优化而省略,且要求每次直接 ...

  6. Django框架(十五)—— forms组件、局部钩子、全局钩子

    目录 forms组件.局部钩子.全局钩子 一.什么是forms组件 二.forms组件的使用 1.使用语法 2.组件的参数 3.注意点 三.渲染模板 四.渲染错误信息 五.局部钩子 1.什么是局部钩子 ...

  7. Python - 元组 , range

    元组和元组嵌套 元组: 俗称不可变的列表.又被成为只读列表, 元组也是python的基本数据类型之一, 用小括号括起来, 里面可以放任何数据类型的数据, 查询可以. 循环也可以. 切片也可以. 但就是 ...

  8. __user表示是一个user mode的pointer,所以kernel不可能直接使用。

    __user表示是一个用户空间的指针,所以kernel不可能直接使用. #ifdef __CHECKER__# define __user __attribute__((noderef, addres ...

  9. Java技术专区-虚拟机系列-虚拟机参数(常用)

    基础参数系类(内存分配) -server:一定要作为第一个参数,在多个CPU时性能佳 -Xmn:young generation的heap大小,一般设置为Xmx的3.4分之一-Xms:初始Heap大小 ...

  10. neo4j APOC与自定义存储过程环境搭建

    neo4j APOC与自定义存储过程环境搭建 主要参考资料:APOC官网https://neo4j-contrib.github.io/neo4j-apoc-procedures/APOC介绍 PPT ...