A.最长路

题意:给定有向图,每条边有个字符\([0,10^9]\),求每个点最长路字典序最小的方案.\(N,M\le 10^6\)

建反图跑拓扑排序,显然入过队的点都有最长路,考虑如何判断字典序大小,一种方案是把每个点转移过来的路径字符串哈希一下,然后用倍增比较两个字符串的大小复杂度\(O(N+Mlog_2M)\)

第二种方案是每次对最长路相同的点以入边上的字符为第一关键字,起点的排名(之前已经排过了)为第二关键字排序,这样可以保证字典序小的先更新

代码是第一种方法

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i(a);i<=(b);++i)
#define dbg(x) cout<<#x<<" = "<<(x)<<endl
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
using namespace std;
inline int read(){
int f=1,x=0;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
return f*x;
}
inline char smin(int&x,const int&y){return x>y?x=y,1:0;}
inline char smax(int&x,const int&y){return x<y?x=y,1:0;}
const int BUFSIZE=1e6;
char inbuf[BUFSIZE],outbuf[BUFSIZE],*si=inbuf,*ti=inbuf,*so=outbuf,*to=outbuf+BUFSIZE;
struct FastIO{
~FastIO(){fwrite(outbuf,1,so-outbuf,stdout);}
#define gc() (si==ti&&(ti=inbuf+fread(si=inbuf,1,BUFSIZE,stdin),si==ti)?EOF:*si++)
#define pc(c) (so==to?fwrite(outbuf,1,BUFSIZE,stdout),so=outbuf,*so++=c:*so++=c)
template<typename T>inline T&rd(T&w){char c,p=0;
while(isspace(c=gc()));if(c=='-')p=1,c=gc();
for(w=c&15;isdigit(c=gc());w=w*10+(c&15));
if(p)w=-w;return w;}
inline int read(){int x;return rd(x);}
template<typename T>inline void print(T w){static char s[20];int top=0;
if(w<0)pc('-'),w=-w;if(w==0)pc('0');
for(top=0;w;w/=10)s[++top]=w%10;
while(top)pc(s[top--]|'0');}
inline void putstr(const string&u){int l=u.length();REP(i,0,l-1)pc(u[i]);}
}io;
#define read io.read
const int N=1e6+5,p=998244353;
int n,m,head[N],tot,L;
struct node{int v,w,nxt;}e[N];
inline void add(int x,int y,int z){e[++tot]=(node){y,z,head[x]};head[x]=tot;}
int q[N],ind[N],f[N],ans[N],fa[23][N];
ull g[23][N],cf[N];
const ull base=1000000007ull;
inline bool cmp(int x,int y){
for(int i=L;~i;--i)if(g[i][x]==g[i][y])x=fa[i][x],y=fa[i][y];
return g[0][x]<g[0][y];
}
void toposort(){
int l=1,r=0,x;
REP(i,1,n)if(!ind[i])q[++r]=i,f[i]=0;
while(l<=r){
for(int i=head[x=q[l++]];i;i=e[i].nxt){
int&y=e[i].v;
if((smax(f[y],f[x]+1)||f[y]==f[x]+1&&(g[0][y]>e[i].w||g[0][y]==e[i].w&&cmp(x,fa[0][y])))){
ans[y]=(ans[x]+e[i].w)*29ll%p;
fa[0][y]=x;g[0][y]=e[i].w;
REP(i,1,L)fa[i][y]=fa[i-1][fa[i-1][y]],g[i][y]=g[i-1][y]*cf[1<<i-1]+g[i-1][fa[i-1][y]];
}
if(!--ind[y])q[++r]=y;
}
}
}
int main(){
n=read(),m=read();L=__lg(m);
REP(i,1,m){int x=read(),y=read(),z=read();add(y,x,z);++ind[x];}
cf[0]=1;REP(i,1,m)cf[i]=cf[i-1]*base;toposort();
REP(i,1,n){
if(ind[i]<=0)io.print(ans[i]),pc('\n');
else io.putstr("Infinity\n");
}
return 0;
}

B.选择题

题意: 有一道选择题有四个选项 现在有 \(n\)个人来做这题,第 \(i\)个人有 \(p_{i,j}\) 的概率选第 \(j\) 个选项。 定义 \(cnt(x)\) 为选第 \(x\) 个选项的人数。 令 \(mx\) 为 \(cnt(x)\) 最大的 \(x\) (如果有多个\(cnt(x)\)最大的 \(x\),则取其中 \(x\) 最小的), 若 ,则所有人得 0 分; 否则令 \(choice_i\) 表示第 \(i\) 个人选的选项,则第 i 人得 分。 求每个人的期望得分。

\(n\le 2000\)

考虑枚举这个最多的是哪个选项,然后只要对每个 \(i\) 算出他选每个选项的概率即可

设 \(f[i][j]\) 表示前 \(i\) 个人,选了 \(j\) 个 \(mx\) 的概率,那么有

\[f[i][j]=f[i-1][j-1]*p[i][mx]+f[i-1][j]*(1-p[i][mx])
\]

设 \(g[i][j]\) 表示\(i \dots n\) ,选了 \(j\) 个 \(mx\) 的概率,转移同理

这样对 \(g\) 做个后缀和就可以算了

复杂度 \(O(16n^2)\)

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i(a);i<=(b);++i)
#define dbg(x) cout<<#x<<" = "<<(x)<<endl;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
using namespace std;
inline int read(){
int f=1,x=0;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
return f*x;
}
inline char smin(int&x,const int&y){return x>y?x=y,1:0;}
inline char smax(int&x,const int&y){return x<y?x=y,1:0;}
struct FastIO{
static const int S=1310720;
int wpos;char wbuf[S];
FastIO():wpos(0) {}
inline int xchar(){
static char buf[S];
static int len=0,pos=0;
if(pos==len)pos=0,len=fread(buf,1,S,stdin);
if(pos==len)return -1;
return buf[pos++];
}
inline int read(){
int c=xchar(),x=0;
while(c<=32&&~c)c=xchar();
if(c==-1)return -1;
for(;'0'<=c&&c<='9';c=xchar())x=x*10+c-'0';
return x;
}
}io;
#define read io.read
const int N=2005,p=998244353;
int n,a[4][N],f[N][N],g[N][N],w[4][N],ans[N];
inline void inc(int&x,int y){x+=y;if(x>=p)x-=p;}
int main(){
n=read();
REP(i,1,n)REP(j,0,3)a[j][i]=read();
REP(i,0,3)REP(j,0,3)w[i][j]=read();
int m=n/2+1;
REP(k,0,3){
memset(f,0,sizeof f);memset(g,0,sizeof g);
f[0][0]=g[n+1][0]=1;
REP(i,1,n)REP(j,0,i)
f[i][j]=((j?1ll*a[k][i]*f[i-1][j-1]%p:0)+1ll*(1-a[k][i]+p)*f[i-1][j])%p;
for(int i=n;i;--i)for(int j=n-i+1;~j;--j)
g[i][j]=((j?1ll*a[k][i]*g[i+1][j-1]%p:0)+1ll*(1-a[k][i]+p)*g[i+1][j])%p;
REP(i,1,n)for(int j=n-i+1;~j;--j)inc(g[i][j],g[i][j+1]);
REP(i,1,n)REP(j,0,i-1)if(f[i-1][j]){
REP(t,0,3)if(t==k)ans[i]=(ans[i]+1ll*f[i-1][j]*g[i+1][max(0,m-1-j)]%p*a[k][i]%p*w[k][k])%p;
else ans[i]=(ans[i]+1ll*f[i-1][j]*g[i+1][max(0,m-j)]%p*a[t][i]%p*w[k][t])%p;
}
}
REP(i,1,n)printf("%d\n",ans[i]);
return 0;
}

C.树

题意:给一棵树,有边权,实现4种操作:

1.链查询权值和

2.链修改父亲边的权值

3.链修改儿子边的权值

4.换根查询子树和

数据结构题,按照题意写即可。先树剖,然后线段树里维护一下对父亲的修改,对儿子的修改,和父亲边的权值和,跳轻重链时,轻边上判一下父亲和儿子谁先改即可。

复杂度 \(O(nlog^2n)\)

#include<bits/stdc++.h>
#define REP(i,a,b) for(int i(a);i<=(b);++i)
#define dbg(x) cout<<#x<<" = "<<(x)<<endl;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
using namespace std;
inline int read(){
int f=1,x=0;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
return f*x;
}
inline char smin(int&x,const int&y){return x>y?x=y,1:0;}
inline char smax(int&x,const int&y){return x<y?x=y,1:0;}
struct FastIO{
static const int S=1310720;
char buf[S],wbuf[S],*si=buf,*ti=buf,*so=wbuf,*to=wbuf+S;
~FastIO(){fwrite(wbuf,1,so-wbuf,stdout);}
#define gc (si==ti&&(ti=buf+fread(si=buf,1,S,stdin),si==ti)?EOF:*si++)
template<typename T>inline void read(T&w){register char c,p=0;
while(isspace(c=gc));if(c=='-')p=1,c=gc;
for(w=c&15;isdigit(c=gc);w=w*10+(c&15));if(p)w=-w;
}
inline int read(){register int x;return read(x),x;}
#define pc(c) (so==to?fwrite(wbuf,1,S,stdout),so=wbuf,*so++=c:*so++=c)
template<typename T>inline void print(T w,char c='\n'){
static char s[25];int top=0;
if(w<0)pc('-'),w=-w;if(w==0)pc('0');
for(top=0;w;w/=10)s[++top]=w%10;
while(top)pc(s[top--]|'0');pc(c);
}
#undef gc
}io;
#define read io.read
const int N=1e5+5;
int n,m,head[N],v[N<<1],nxt[N<<1],tot;
inline void add(int x,int y){v[++tot]=y,nxt[tot]=head[x];head[x]=tot;}
int top[N],in[N],siz[N],fa[N],dep[N],son[N],cnt;
#define y v[i]
inline void go1(int x){
siz[x]=1;
for(int i=head[x];i;i=nxt[i])if(y!=fa[x])
fa[y]=x,dep[y]=dep[x]+1,go1(y),siz[x]+=siz[y],siz[y]>siz[son[x]]&&(son[x]=y);
}
inline void go2(int x,int anc){
in[x]=++cnt;top[x]=anc;
if(!son[x])return;go2(son[x],anc);
for(int i=head[x];i;i=nxt[i])if(y!=fa[x]&&y!=son[x])go2(y,y);
}
#undef y
#define ls o<<1
#define rs o<<1|1
#define all 1,1,n
struct data{int t,w;};
struct tree{int sum[3],len;data tag,son;}t[N<<2];
int T,opt;
inline void pushup(int o){REP(i,0,2)t[o].sum[i]=t[ls].sum[i]+t[rs].sum[i];}
inline void build(int o,int l,int r){
t[o].sum[0]=t[o].len=r-l+1;
t[o].tag=t[o].son=(data){-1,-1};
if(l==r){t[o].tag=(data){0,0};return;}
int mid=l+r>>1;build(ls,l,mid),build(rs,mid+1,r);
}
inline void change(int o,const data&x,bool f){
if(f){
REP(i,0,2)t[o].sum[i]=i==x.w?t[o].len:0;t[o].tag=x;
}else t[o].son=x;
}
#define pushdown()\
if(~t[o].tag.t)change(ls,t[o].tag,1),change(rs,t[o].tag,1),t[o].tag=(data){-1,-1};\
if(~t[o].son.t)change(ls,t[o].son,0),change(rs,t[o].son,0),t[o].son=(data){-1,-1};
inline void update(int o,int l,int r,int x,int y,const data&z){
if(x>y)return;if(x<=l&&r<=y)return change(o,z,opt);
int mid=l+r>>1;pushdown();
if(x<=mid)update(ls,l,mid,x,y,z);if(y>mid)update(rs,mid+1,r,x,y,z);
pushup(o);
}
inline int ask(int o,int l,int r,int x,int y,int z){
if(x<=l&&r<=y)return t[o].sum[z];
if(x>r||y<l||x>y)return 0;
int mid=l+r>>1;pushdown();
return ask(ls,l,mid,x,y,z)+ask(rs,mid+1,r,x,y,z);
}
inline data&ask(int o,int l,int r,int x,int z){
if(l==r)return z?t[o].tag:t[o].son;
int mid=l+r>>1;pushdown();
return x<=mid?ask(ls,l,mid,x,z):ask(rs,mid+1,r,x,z);
}
data t1,t2;
inline int ask(int x,int y,int z){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans+=ask(all,in[top[x]]+1,in[x],z);
t1=ask(all,in[top[x]],1);t2=ask(all,in[fa[top[x]]],0);
if(t1.t>=t2.t)ans+=t1.w==z;else ans+=t2.w==z;
x=fa[top[x]];
}
if(x==y)return ans;
if(dep[x]>dep[y])swap(x,y);
return ans+ask(all,in[x]+1,in[y],z);
}
inline void update(int x,int y,int c1,int c2){
++T;t1=(data){T,c1},t2=(data){T,c2};
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
opt=0,update(all,in[top[x]],in[x],t2);
opt=1,update(all,in[top[x]],in[x],t1);
if(son[x])update(all,in[x]+1,in[x]+1,t2);
x=fa[top[x]];
} if(dep[x]>dep[y])swap(x,y);
opt=0,update(all,in[x],in[y],t2);
opt=1,update(all,in[x]+1,in[y],t1);
update(all,in[x],in[x],t2);
if(son[y])update(all,in[y]+1,in[y]+1,t2);
}
inline int jump(int x,int y){while(top[x]!=top[y])if(fa[top[x]]==y)return top[x];else x=fa[top[x]];return son[y];}
int main(){
n=read();
REP(i,2,n){int x=read(),y=read();add(x,y),add(y,x);}
go1(1),go2(1,1),build(1,1,n);
m=read();
while(m--){
int op=read(),x=read(),y=read(),z=read();
if(op==1)io.print(ask(x,y,z));
else if(op==2)update(x,y,z,read());
else{
opt=1;t1=(data){++T,z};
if(x==y)update(all,1,n,t1);else
if(in[x]>in[y]&&in[x]<in[y]+siz[y]){
int p=jump(x,y);
update(all,1,in[p]-1,t1),update(all,in[p]+siz[p],n,t1);
}else update(all,in[y]+1,in[y]+siz[y]-1,t1);
}
}
return 0;
}

[NowCoder]牛客网NOIP赛前集训营-提高组(第六场)题解的更多相关文章

  1. 牛客网NOIP赛前集训营-普及组(第二场)和 牛客网NOIP赛前集训营-提高组(第二场)解题报告

    目录 牛客网NOIP赛前集训营-普及组(第二场) A 你好诶加币 B 最后一次 C 选择颜色 D 合法括号序列 牛客网NOIP赛前集训营-提高组(第二场) A 方差 B 分糖果 C 集合划分 牛客网N ...

  2. 牛客网NOIP赛前集训营-提高组(第二场)A 方差

    链接:https://www.nowcoder.com/acm/contest/173/A来源:牛客网 题目描述 一个长度为 m 的序列 b[1...m] ,我们定义它的方差为 ,其中  表示序列的平 ...

  3. [牛客网NOIP赛前集训营-提高组(第一场)]C.保护

    链接:https://www.nowcoder.com/acm/contest/172/C来源:牛客网 题目描述 C国有n个城市,城市间通过一个树形结构形成一个连通图.城市编号为1到n,其中1号城市为 ...

  4. 牛客网NOIP赛前集训营-提高组(第一场)

    牛客的这场比赛感觉真心不错!! 打得还是很过瘾的.水平也比较适合. T1:中位数: 题目描述 小N得到了一个非常神奇的序列A.这个序列长度为N,下标从1开始.A的一个子区间对应一个序列,可以由数对[l ...

  5. Nowcoder牛客网NOIP赛前集训营-提高组(第六场)

    A 拓扑排序+倍增哈希 或者 拓扑排序对于每个点计一个rank,每个点优先选取rank靠前的最小边权点 每次依然按照rank排序更新rank #include<bits/stdc++.h> ...

  6. [NowCoder]牛客网NOIP赛前集训营-提高组(第七场)

    链接 A.中国式家长2 模拟题,毫无坑点 #include<bits/stdc++.h> #define REP(i,a,b) for(int i(a);i<=(b);++i) #d ...

  7. 比赛总结——牛客网 NOIP赛前集训营提高组模拟第一场

    第一场打的很惨淡啊 t1二分+前缀最小值没想出来,20分的暴力也挂了,只有10分 t2数位dp,调了半天,结果因为忘了判0的特殊情况WA了一个点,亏死 t3emmmm.. 不会 imone说是DSU ...

  8. 牛客网NOIP赛前集训营-提高组(第一场)B 数数字

    数数字 思路: 数位dp 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include< ...

  9. 牛客网NOIP赛前集训营-提高组(第一场)A 中位数

    中位数 思路: 二分答案 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include< ...

随机推荐

  1. Java基础学习总结(19)——Java环境变量配置

    前言 学习java的第一步就要搭建java的学习环境,首先是要安装JDK,JDK安装好之后,还需要在电脑上配置"JAVA_HOME"."path"." ...

  2. Spring Cloud分布式Session共享实践

    通常情况下,Tomcat.Jetty等Servlet容器,会默认将Session保存在内存中.如果是单个服务器实例的应用,将Session保存在服务器内存中是一个非常好的方案.但是这种方案有一个缺点, ...

  3. HTML学习----------DAY2第五节

    属性为 HTML 元素提供附加信息. HTML 属性 HTML 标签可以拥有属性.属性提供了有关 HTML 元素的更多的信息. 属性总是以名称/值对的形式出现,比如:name="value& ...

  4. 关于Windows7下创建Cocos2D-X项目的小问题

    "新版的Cocos2D-X"已经不支持用上述脚本来创建工程了,而是改为用create-project.py来创建...命令格式: python create-project.py ...

  5. android YUV Sensor配置Camera应用的flash auto菜单

    请在Config.ftbl.flashlight.h (mediatek\custom\common\hal\flashlight\src)中. 将全部的两处凝视掉的code: //CameraPar ...

  6. VC++中的延时函数

    原文链接:http://www.educity.cn/develop/478947.html VC中提供了很多关于时间操作的函数,编写程序时我们可以跟据定时的不同精度要求选择不同的时间函数来完成定时和 ...

  7. UESTC 30最短路(flyod算法)

    最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  8. Flex 集合 ArrayCollection 的使用

    转:http://keren.iteye.com/blog/380847 转:http://callan.iteye.com/blog/335551 集合是ActionScript 中功能强大的基于索 ...

  9. 【Linux下安装配置Jupyter】

    """ 第一步 安装 """ pip3 install -i https://pypi.douban.com/simple jupyter ...

  10. Mark Sweep GC

    目录 标记清除算法 标记阶段 深度优先于广度优先 清除阶段 分配 First-fit.Best-fit.Worst-fit三种分配策略 合并 优点 实现简单 与保守式GC算法兼容 缺点 碎片化 分配速 ...