题目描述



题解

吼题但题解怎么这么迷

考虑一种和题解不同的做法(理解)

先把僵尸离散化,h相同的钦(ying)点一个大小

(可以发现这样每种情况只会被算正好一次)

计算完全被占领的方案,然后1-方案/概率

由于大小确定了,所以最后会被分成若干不相连的块,且块中至少有一只僵尸,大的僵尸能占领小的僵尸的块,所以相邻两块之间一定会断开

那么一种占领的方案对应的是一类高度情况,考虑所有的占领方案即可求出所有的高度情况

定义一个块的编号为所占领的最大僵尸的编号

设f[i]x表示以i为根的子树中点i所在块的编号为x

那么对于f[j]y转移如下:

①x=y

f[j][y]*(僵尸x经过i--j的方案数)-->f[i][x]

那么x和y在同一个块中,因为一个块只有一只僵尸,所以块内必须要连通

②x<y

f[j][y]*(僵尸y不经过i--j的方案数)-->f[i][x]

x和y不在同一个块中,所以x和y不能连通,即较大的僵尸(y)不能走到另一个点(i)

并且要保证j中存在y,不存在x,原因见下文

③x>y

f[j][y]*(僵尸x不经过i--j的方案数)-->f[i][x]

原因&范围同上

初值为f[i][x]=[x>=i处最大的僵尸能力值](x>0)

对于②③的限制:

因为要保证以某个点i为最浅点的块内刚好存在僵尸x

在i与fa[i]断开时保证了x在i的子树中,i所在块的叶子与块中叶子的儿子断开保证了x不在块外,所以块中必定存在x

时间复杂度O(n3),前后缀优化成O(n2)

code

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define add(a,b) a=((a)+(b))%998244353
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
#define mod 998244353
#define Mod 998244351
using namespace std; struct type{
int x,id;
} b[2001];
int a[4002][2];
int c[2001][2001];
int C[2001];
int ls[2001];
int L[2001];
int R[2001];
int h[2001];
int H[2001];
long long f[2001][2001];
long long s1[2002];
long long s2[2002];
bitset<2001> bz[2001];
int T,N,n,m,i,j,k,l,len;
long long ans,s; bool cmp(type a,type b)
{
return a.x<b.x;
} void New(int x,int y)
{
++len;
a[len][0]=y;
a[len][1]=ls[x];
ls[x]=len;
} long long qpower(long long a,int b)
{
long long ans=1; while (b)
{
if (b&1)
ans=ans*a%mod; a=a*a%mod;
b>>=1;
} return ans;
} void Dfs(int Fa,int t)
{
int i; if (h[t]) bz[t][h[t]]=1; for (i=ls[t]; i; i=a[i][1])
if (a[i][0]!=Fa)
{
Dfs(t,a[i][0]);
bz[t]|=bz[a[i][0]];
}
} void dfs(int Fa,int t)
{
int i,j,k,l,id;
long long x; fo(i,max(1,h[t]),N) f[t][i]=1; for (i=ls[t]; i; i=a[i][1])
if (a[i][0]!=Fa)
{
id=i/2;
dfs(t,a[i][0]); fo(k,1,N)
{
s1[k]=s1[k-1]; if (bz[a[i][0]][k])
add(s1[k],f[a[i][0]][k]);
}
s2[N+1]=0;
fd(k,N,1)
{
s2[k]=s2[k+1]; if (bz[a[i][0]][k])
add(s2[k],f[a[i][0]][k]*max(R[id]-max(H[k],L[id])+1,0)%mod);
} fo(j,1,N)
{
if (!bz[a[i][0]][j])
f[t][j]=f[t][j]*(s2[j+1]+s1[j-1]*max(R[id]-max(H[j],L[id])+1,0)%mod+f[a[i][0]][j]*max(min(H[j]-1,R[id])-L[id]+1,0)%mod)%mod;
else
f[t][j]=f[t][j]*(f[a[i][0]][j]*max(min(H[j]-1,R[id])-L[id]+1,0)%mod)%mod; // O(n^3)
// fo(k,1,N)
// if (f[a[i][0]][k])
// {
// if (j<k)
// x=max(R[id]-max(H[k],L[id])+1,0);
// if (j==k)
// x=max(min(H[k]-1,R[id])-L[id]+1,0);
// if (j>k)
// x=max(R[id]-max(H[j],L[id])+1,0);
//
// if (j==k || bz[a[i][0]][k] && !bz[a[i][0]][j])
// add(F[j],f[t][j]*f[a[i][0]][k]%mod*x);
// }
}
}
} int main()
{
freopen("zombie.in","r",stdin);
freopen("zombie.out","w",stdout); scanf("%d",&T);
for (;T;--T)
{
memset(bz,0,sizeof(bz));
memset(ls,0,sizeof(ls));
memset(h,0,sizeof(h));
memset(H,0,sizeof(H));
memset(f,0,sizeof(f));
memset(C,0,sizeof(C));
len=1; scanf("%d%d",&n,&m);
fo(i,1,n-1)
{
scanf("%d%d%d%d",&j,&k,&L[i],&R[i]); New(j,k);
New(k,j);
}
fo(i,1,m)
{
scanf("%d%d",&j,&k);
h[j]=max(h[j],k);
} N=0;
fo(i,1,n)
if (h[i])
b[++N]={h[i],i}; sort(b+1,b+N+1,cmp); fo(i,1,N)
{
H[i]=b[i].x;
h[b[i].id]=i;
} Dfs(0,1);
dfs(0,1); ans=0;
fo(i,1,N)
add(ans,f[1][i]); s=1;
fo(i,1,n-1)
s=s*(R[i]-L[i]+1)%mod;
ans=ans*qpower(s,Mod)%mod; printf("%lld\n",((1-ans)%mod+mod)%mod);
} fclose(stdin);
fclose(stdout); return 0;
}

6392. 【NOIP2019模拟2019.10.26】僵尸的更多相关文章

  1. 6389. 【NOIP2019模拟2019.10.26】小w学图论

    题目描述 题解 之前做过一次 假设图建好了,设g[i]表示i->j(i<j)的个数 那么ans=∏(n-g[i]),因为连出去的必定会构成一个完全图,颜色互不相同 从n~1染色,点i的方案 ...

  2. 6377. 【NOIP2019模拟2019.10.05】幽曲[埋骨于弘川]

    题目描述 题解 随便bb 详细题解见 https://www.cnblogs.com/coldchair/p/11624979.html https://blog.csdn.net/alan_cty/ ...

  3. 【NOIP2019模拟2019.10.07】果实摘取 (约瑟夫环、Mobius反演、类欧、Stern-Brocot Tree)

    Description: 小 D 的家门口有一片果树林,果树上果实成熟了,小 D 想要摘下它们. 为了便于描述问题,我们假设小 D 的家在二维平面上的 (0, 0) 点,所有坐标范围的绝对值不超过 N ...

  4. 6383. 【NOIP2019模拟2019.10.07】果实摘取

    题目 题目大意 给你一个由整点组成的矩形,坐标绝对值范围小于等于\(n\),你在\((0,0)\),一开始面向\((1,0)\),每次转到后面第\(k\)个你能看到的点,然后将这条线上的点全部标记删除 ...

  5. 6380. 【NOIP2019模拟2019.10.06】小w与最长路(path)

    题目 题目大意 给你一棵树,对于每一条边,求删去这条边之后,再用一条边(自己定)连接两个连通块,形成的树的直径最小是多少. 正解 首先,将这棵树的直径给找出来.显然,如果删去的边不在直径上,那么答案就 ...

  6. 6374. 【NOIP2019模拟2019.10.04】结界[生与死的境界]

    题目 题目大意 给你一个数列,每次可以选择任意两个相邻的数\(x\)和\(y\),将其删去,并在原来位置插入\(x+2y\). 每次询问一个区间,对这个区间进行上述操作.求最后剩下的数最大是多少. 答 ...

  7. 2019.10.26 csp-s模拟测试88 反思总结

    今天的主人公是什么? 60.1K!!!! 先扔代码再更新防止我等会儿一上头不打算写完题解 T1: #include<iostream> #include<cstdio> #in ...

  8. 2019.10.26 CSP%您赛第三场

    \(CSP\)凉心模拟^_^ --题源\(lqx.lhc\)等各位蒟蒻 题目名称 比赛 传递消息 开关灯 源文件名 \(competition.cpp\) \(message.cpp\) \(ligh ...

  9. 6424. 【NOIP2019模拟2019.11.13】我的订书机之恋

    题目描述 Description Input Output Sample Input 见下载 Sample Output 见下载 Data Constraint 题解 lj题卡线段树 求出每个右端点往 ...

随机推荐

  1. IntelliJ IDEA 2019.1.1 maven框架web.xml中web-app版本过低导致不能正常使用EL表达式的解决方案

     1.软件版本 IDEA版本:IntelliJ IDEA 2019.1.1 maven版本:apache-maven-3.6.1 Tomcat版本:tomcat-8.5 2.问题描述 IDEA使用如下 ...

  2. 【FICO系列】SAP ABAP&FI FI/CO接口:待更新的不一致的FI/CO凭证标题数据

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[FICO系列]SAP ABAP&FI ...

  3. Java中个容器的对比

    List: 有序,列表存储,元素可重复 Set: 无序,元素不可重复 Map:无序,元素可重复,key不能重复 LinkedList :链表,删除和添加效率很高,随机访问效率较ArrayList类低, ...

  4. mybatis使用map传递多参数报错:A query was run and no Result Maps were found for the Mapped Statement

    在使用mybatis进行多参数传递时,报错: A query was run and no Result Maps were found for the Mapped Statement 'xx.xx ...

  5. java锁的使用

    1 synchronize和ReentrantLock synchronize锁是jvm内置的锁,它锁的是synchronize所在的类的对象,要同步那么就只能有一个对象. ReentrantLock ...

  6. 右键windows terminal here无法进入当前目录

    很久没写水笔了,简单记一水 使用windows terminal的基本上都自己改过注册表,添加到右键windows terminal here吧,用着很方便,哪里不会点哪里. 我起初删除掉starti ...

  7. C++中的赋值操作符重载和拷贝构造函数

    1,关于赋值的疑问: 1,什么时候需要重载赋值操作符? 2,编译器是否提供默认的赋值操作符? 2,关于赋值的疑问: 1,编译器为每个类默认重载了赋值操作符: 1,意味着同类型的类对象可以相互赋值: 2 ...

  8. Aliyun-Centos 7 LNMP安装(最新版LNMP)

    linux装软件方式:1.源码安装:下载wget-->解压tar -zxvf -->配置 ./configure --->编译make -->安装 make install 2 ...

  9. Desert King(01分数规划问题)(最优斜率生成树)

    Desert King Time Limit: 3000MS   Memory Limit: 65536K Total Submissions:33847   Accepted: 9208 Descr ...

  10. SQL Server to MySQL

    使用 Navicat 导入向导迁移 会遇到以下问题 SQL Server 中的 GUID 类型字段会变成 {guid} 多个外层花括号, 导致程序问题. 部分字段类型长度不大一致, 需要手工调整. . ...