JSOI2018R2题解
D1T1:潜入行动
裸的树上DP。f[i][j][0/1][0/1]表示以i为根的子树放j个设备,根有没有放,根有没有被子树监听,的方案数。转移显然。
#include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long long ll;
using namespace std; const int N=,mod=1e9+;
ll tmp[][][];
int n,k,cnt,u,v,sz[N],dp[N][][][],h[N],to[N<<],nxt[N<<]; void ins(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
void add(int &x,ll y){ if (x+y>=mod) x=x+y-mod; else x=x+y; } void dfs(int x,int fa){
sz[x]=; dp[x][][][]=; dp[x][][][]=;
for (int i=h[x]; i; i=nxt[i]){
int v=to[i];
if (v==fa) continue;
dfs(v,x);
int tx=min(k,sz[x]),tv=min(k,sz[v]);
rep(j,,tx) rep(a,,) rep(b,,)
tmp[j][a][b]=dp[x][j][a][b],dp[x][j][a][b]=;
rep(j,,tx){
for(int a=; a<=tv && j+a<=k; a++){
add(dp[x][j+a][][],tmp[j][][]*dp[v][a][][]%mod);
add(dp[x][j+a][][],(tmp[j][][]*dp[v][a][][]+tmp[j][][]*(dp[v][a][][]+dp[v][a][][]))%mod);
add(dp[x][j+a][][],tmp[j][][]*(dp[v][a][][]+dp[v][a][][])%mod);
add(dp[x][j+a][][],(tmp[j][][]*(dp[v][a][][]+dp[v][a][][])+tmp[j][][]*(dp[v][a][][]+dp[v][a][][])+tmp[j][][]*(dp[v][a][][]+dp[v][a][][]))%mod);
}
}
sz[x]+=sz[v];
}
} int main(){
freopen("action.in","r",stdin);
freopen("action.out","w",stdout);
scanf("%d%d",&n,&k);
rep(i,,n) scanf("%d%d",&u,&v),ins(u,v),ins(v,u);
dfs(,-);
printf("%d\n",(dp[][k][][]+dp[][k][][])%mod);
return ;
}
D1T1
D2T2:防御网络
https://blog.csdn.net/scar_lyw/article/details/80410420
首先连接环的桥边的贡献很好算,tarjan过程中可直接求出。然后对于每一个环,求出环上被选中边数的期望。
一个环被选中的边,一定是环长减去最大的一个空隙。我们枚举环上的[s,s+len]中的点被选中(一个点被选中当且仅当子图S中包含这个点或这个点连出的外向树中的点)。设DP状态dp[s][len][k]表示[s,s+len]中有点且这段的最大空隙为k的方案数。求出dp数组后贡献就很容易求得了,注意还有一个空隙是环长-len。
#include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
#define For(i,x) for (int i=h[x],k; i; i=nxt[i])
using namespace std; const int N=,mod=1e9+;
int n,m,u,v,cnt,ans,f[N],p2[N],sz[N],vis[N],fa[N];
int dp[N][],sm[N][],h[N],to[N],nxt[N],dep[N];
void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; } int ksm(int a,int b){
int res=;
for (; b; a=1ll*a*a%mod,b>>=)
if (b & ) res=1ll*res*a%mod;
return res;
} void calc(int s,int len,int n){
rep(i,s-,n) dp[i][]=dp[i][]=sm[i][]=sm[i][]=;
dp[s][]=sm[s][]=f[s];
rep(i,s+,n){
int l=max(s,i-len+)-;
if (i-len>=s) dp[i][]=(dp[i][]+1ll*(dp[i-len][]+dp[i-len][])*f[i])%mod;
dp[i][]=(dp[i][]+1ll*f[i]*(sm[i-][]-sm[l][]+mod))%mod;
dp[i][]=(dp[i][]+1ll*f[i]*(sm[i-][]-sm[l][]+mod))%mod;
sm[i][]=(sm[i-][]+dp[i][])%mod; sm[i][]=(sm[i-][]+dp[i][])%mod;
ans=(ans+1ll*min(i-s,n-len)*dp[i][])%mod;
}
} void solve(int u,int v){
int cur=v,lst=,tot=;
for (; cur!=u; lst=cur,cur=fa[cur])
f[++tot]=p2[sz[cur]-sz[lst]],vis[cur]=;
f[++tot]=p2[n-sz[lst]];
rep(i,,tot-) rep(j,,tot-i) calc(i,j,tot);
} void dfs(int x){
dep[x]=dep[fa[x]]+; sz[x]=;
For(i,x) if (!dep[k=to[i]]) fa[k]=x,dfs(k),sz[x]+=sz[k];
else if (dep[k]>dep[x]) solve(x,k);
} int main(){
freopen("defense.in","r",stdin);
freopen("defense.out","w",stdout);
scanf("%d%d",&n,&m);
rep(i,,m) scanf("%d%d",&u,&v),add(u,v),add(v,u);
p2[]=; rep(i,,n) p2[i]=p2[i-]*2ll%mod;
rep(i,,n) p2[i]--;
dfs();
rep(i,,n) if (!vis[i]) ans=(ans+1ll*p2[sz[i]]*p2[n-sz[i]])%mod;
ans=1ll*ans*ksm(p2[n]+,mod-)%mod;
printf("%d\n",ans);
return ;
}
D2T2
D1T3:绝地反击
如果确定这个正n边形的话,二分+Dinic就好了。退火/爬山旋转正n边形即可。
正解是网络流退流,未看。
D2T1:部落战争
https://www.cnblogs.com/HocRiser/p/10268249.html
D2T2:扫地机器人
留坑。
D2T3:军训列队
显然集合后每个人的相对位置可以不改变,那么把所求的式子列出来就会发现是一些定值加上关于每个人的坐标和集合点的差的绝对值的数。拆成两部分,显然左半部分向右走,右半部分向左走。
在主席树上二分这个分界点,维护区间中点的坐标和,剩下的直接求解。
#include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
#define lson ls[x],L,mid
#define rson rs[x],mid+1,R
typedef long long ll;
using namespace std; const int N=,M=;
ll c,sum[N],sm[M];
int n,Q,m,l,r,k,K,nd,a[N],rt[N],v[M],ls[M],rs[M]; void ins(int y,int &x,int L,int R,int k){
x=++nd; ls[x]=ls[y]; rs[x]=rs[y]; v[x]=v[y]+; sm[x]=sm[y]+k;
if (L==R) return;
int mid=(L+R)>>;
if (k<=mid) ins(ls[y],lson,k); else ins(rs[y],rson,k);
} int que(int x,int y,int L,int R,int k){
if (L==R){ c+=sm[x]-sm[y]; return v[x]-v[y]; }
int mid=(L+R)>>,t=v[ls[x]]-v[ls[y]];
if (k+t-<mid) return que(ls[x],ls[y],L,mid,k);
else{
c+=sm[ls[x]]-sm[ls[y]];
return v[ls[x]]-v[ls[y]]+que(rs[x],rs[y],mid+,R,k+t);
}
} int main(){
freopen("line.in","r",stdin);
freopen("line.out","w",stdout);
scanf("%d%d",&n,&Q);
rep(i,,n) scanf("%d",&a[i]),m=max(m,a[i]),sum[i]=sum[i-]+a[i];
rep(i,,n) ins(rt[i-],rt[i],,m,a[i]);
while (Q--){
scanf("%d%d%d",&l,&r,&k); c=;
int tot=que(rt[r],rt[l-],,m,k),len=r-l+;
ll s1=1ll*tot*k+1ll*tot*(tot-)/-c;
ll s2=sum[r]-sum[l-]-c-1ll*(len-tot)*k-1ll*(tot+len-)*(len-tot)/;
printf("%lld\n",s1+s2);
}
return ;
}
D2T3
JSOI2018R2题解的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
随机推荐
- C# 安装部署Windows服务脚本
@echo off Installutil.exe 程序目录 F:\test\TestWindows.exe 服务程序目录 @sc start "服务名称" @sc config ...
- vue dev开发环境跨域和build生产环境跨域问题解决
dev开发时解决请求跨域问题:config-index.js 配置代理dev: { env: require('./dev.env'), port: 8082, assetsSubDirectory: ...
- J - Borg Maze +getchar 的使用注意(二维字符数组的输入)
题目链接: https://vjudge.net/contest/66965#problem/J 具体思路: 首先将每个点之间的最短距离求出(bfs),A 或者 S作为起点跑bfs,这样最短距离就求出 ...
- qt 零星笔记
1.qt中堆栈对象的销毁 名字不对,我不知道该取个什么名字,暂且这样吧 在linux c编程中谈到过进程的内存映像,一个进程在内存中的映像如下
- MVVM模式的模式简介
MVVM模式简介 MVVM是Model.View.ViewModel的简写,这种模式的引入就是使用ViewModel来降低View和Model的耦合,说是降低View和Model的耦合.也可以说是是降 ...
- Python的日志记录-logging模块的使用
一.日志 1.1什么是日志 日志是跟踪软件运行时所发生的事件的一种方法,软件开发者在代码中调用日志函数,表明发生了特定的事件,事件由描述性消息描述,同时还包含事件的重要性,重要性也称为级别或严重性. ...
- spring 学习之二 AOP编程
AOP概念 AOP, aspect oriented programing,翻译过来就是面向切面编程的意思,那什么叫面向切面编程呢?相对于之前传统的纵向继承方式来对原有功能进行功能扩展, 面向切面编程 ...
- DevExpress GridControl 的数据绑定
本人不才啊,折腾2个多小时才把数据绑定好.现在把折腾过程记录一下来以帮助更多的朋友,自己也温习一下. 直接上代码了哈.... WPF哈 xaml文件 <dxg:GridControl Name= ...
- Java线程:新特征-有返回值的线程《转》
原始文章 在Java5之前,线程是没有返回值的,常常为了“有”返回值,破费周折,而且代码很不好写.或者干脆绕过这道坎,走别的路了. 现在Java终于有可返回值的任务(也可以叫做线程)了. ...
- MICROSOFT SQLSERVER 总结
--语 句 功 能--数据操作Select --从数据库表中检索数据行和列Insert --向数据库表添加新数据行Delete --从数据库表中删除数据行Update --更新数据库表中的数据--数据 ...