3.22 模拟赛

T1 sort

题目大意:

思路:

T2 mission

题解链接

考场的$dsu \space on \space tree$被卡掉了,写一波主席树合并

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define db double
 4 #define inf 2139092143
 5 #define MAXN 10100
 6 #define DMAXN 640100
 7 #define DMAXM 1280100
 8 #define MOD 998244353
 9 #define rep(i,s,t) for(register int i=(s),i##end=(t);i<=i##end;++i)
10 #define dwn(i,s,t) for(register int i=(s),i##end=(t);i>=i##end;--i)
11 #define ren for(int i=fst[x];i;i=nxt[i])
12 #define pls(a,b) (a+b)%MOD
13 #define mns(a,b) (a-b+MOD)%MOD
14 #define mul(a,b) (1LL*a*b)%MOD
15 #define ist(u,v,w) D::ins(u,v,w)
16 using namespace std;
17 inline int read()
18 {
19     int x=0,f=1;char ch=getchar();
20     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
21     while(isdigit(ch)) {x=x*10+ch-'0',ch=getchar();}
22     return x*f;
23 }
24 int n,m,fst[MAXN],nxt[MAXN<<1],to[MAXN<<1],cnt,val[MAXN],fa[MAXN];
25 int tot,ls[MAXN<<6],rs[MAXN<<6],ss,tt,rt[MAXN];
26 namespace D
27 {
28     int S,T,fst[DMAXN],nxt[DMAXM<<1],to[DMAXM<<1],val[DMAXM<<1],cnt;
29     int cur[DMAXN],vis[DMAXN],dis[DMAXN],q[DMAXN],l,r,tot;
30     void mem(){memset(fst,0,sizeof(fst));cnt=1;}
31     void add(int u,int v,int w){nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v,val[cnt]=w;}
32     void ins(int u,int v,int w){add(u,v,w);add(v,u,0);}
33     int bfs()
34     {
35         vis[T]=++tot,dis[T]=0,q[l=r=1]=T;int x;
36         while(l<=r)
37         {
38             x=q[l++];cur[x]=fst[x];ren if(vis[to[i]]!=tot&&val[i^1])
39                 vis[to[i]]=tot,dis[to[i]]=dis[x]+1,q[++r]=to[i];
40         }
41         return vis[S]==tot;
42     }
43     int dfs(int x,int a)
44     {
45         if(x==T||!a) return a;int flw=0,f;
46         for(int& i=cur[x];i&&a;i=nxt[i])
47             if(val[i]&&dis[to[i]]==dis[x]-1&&(f=dfs(to[i],min(a,val[i]))))
48                 val[i]-=f,val[i^1]+=f,a-=f,flw+=f;
49         return flw;
50     }
51     int solve(int s,int t,int ans=0)
52     {
53         S=s,T=t;int f;while(bfs()) ans+=dfs(S,inf);
54         return ans;
55     }
56 };
57 void add(int u,int v){nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
58 void mdf(int &k,int kk,int l,int r,int x)
59 {
60     k=++tot;if(l==r) {ist(k+n,x,inf);return ;}int mid=l+r>>1;
61     if(val[x]<=mid) rs[k]=rs[kk],mdf(ls[k],ls[kk],l,mid,x);
62     else ls[k]=ls[kk],mdf(rs[k],rs[kk],mid+1,r,x);
63 }
64 void query(int k,int l,int r,int a,int b,int x)
65 {
66     if(!k) return ;if(l==a&&r==b) {ist(tot+n,k+n,x);return ;}int mid=l+r>>1;
67     if(b<=mid) query(ls[k],l,mid,a,b,x);else if(a>mid) query(rs[k],mid+1,r,a,b,x);
68     else {query(ls[k],l,mid,a,mid,x);query(rs[k],mid+1,r,mid+1,b,x);}
69 }
70 int merge(int x,int y,int l,int r)
71 {
72     if(!(x*y)) return x|y;int z=++tot,mid=l+r>>1;
73     if(l==r) {ist(z+n,x+n,inf);ist(z+n,y+n,inf);}
74     ls[z]=merge(ls[x],ls[y],l,mid);rs[z]=merge(rs[x],rs[y],mid+1,r);return z;
75 }
76 void dfs(int x){mdf(rt[x],rt[x],1,n,x);ren dfs(to[i]),rt[x]=merge(rt[x],rt[to[i]],1,n);}
77 int main()
78 {
79     freopen("mission.in","r",stdin);
80     freopen("mission.out","w",stdout);
81     n=read(),m=read();rep(i,2,n) fa[i]=read(),add(fa[i],i);rep(i,1,n) val[i]=read();
82     D::mem();dfs(1);ss=0;int x,a,b,t,k;
83     rep(i,1,tot) {if(ls[i]) ist(i+n,ls[i]+n,inf);if(rs[i]) ist(i+n,rs[i]+n,inf);}
84     while(m--)
85         {x=++tot,a=read(),b=read(),k=read(),t=read();ist(ss,x+n,t);query(rt[k],1,n,a,b,t);}
86     tt=n+tot+1;rep(i,1,n) ist(i,tt,1);
87     printf("%d\n",D::solve(ss,tt));
88 }
View Code

T3 path bzoj 3772

题目大意:

一棵树,给出$m$条路径,求选出两个路径使其中一个被另一个完全包含的概率

思路:

猜你喜欢

转载自www.cnblogs.com/yyc-jack-0920/p/10583184.html