首页 > 其他分享 >[省选联考 2022] 填树 题解

[省选联考 2022] 填树 题解

时间:2023-02-15 11:33:22浏览次数:45  
标签:210 省选 题解 int edge sumg sumf 联考 mod

神奇 dp。发现我看到 dp 大多数时候只会暴力。那我约等于退役了啊。

题意:自己看。

首先有一个显然的暴力。枚举一个最小值 \(L\),然后区间就限定在了 \([L,L+K]\)。那么普及组都能看出来这个 dp 可以前缀和优化。然后由于这个 dp 不能确定最小值一定取到,所以减一个 \([L+1,L+K]\) 的答案。这玩意复杂度显然 \(O(n\times 值域)\) 的。

然后考虑到每次最小值 \(+1\) ,最大值 \(+1\) 的过程。如果没有节点的 \([l_i,r_i]\) 被包含进去或者不再被包含,那么相当于让所有情况下的值 \(+1\)。如果将每个节点的可选区间表示成一次函数的形式,那么可以发现方案数就是所有节点的函数乘起来的 \(n\) 次多项式,求和就是再多一次。

而且这个段数显然是 \(O(n)\) 的。那么对于每一段前缀和拉格朗日插值一下就行了。总复杂度 \(O(n^3)\)。

然而这题有点 jb 卡常。不知道什么心态。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int mod=1000000007;
int n,K,ans1,ans2;
struct node{
    int v,next;
}edge[410];
int t,head[210];
void add(int u,int v){
    edge[++t].v=v;edge[t].next=head[u];head[u]=t;
}
int l[210],r[210];
int f[210],g[210],sumf[210],sumg[210];
int s(int n){
    return 1ll*n*(n+1)/2%mod;
}
void dfs(int x,int fa,int L,int R){
    int l1=max(L,l[x]),r1=min(R,r[x]);
    if(l1>r1)l1=r1+1;
    int ret=r1-l1+1,tmp=(s(r1)-s(l1-1)+mod)%mod;
    f[x]=sumf[x]=ret;g[x]=sumg[x]=tmp;
    for(int i=head[x];i;i=edge[i].next){
        if(edge[i].v!=fa){
            dfs(edge[i].v,x,L,R);
            f[x]=(f[x]+1ll*sumf[x]*sumf[edge[i].v])%mod;
            g[x]=(g[x]+1ll*sumf[x]*sumg[edge[i].v]+1ll*sumf[edge[i].v]*sumg[x])%mod;
            sumf[x]=(sumf[x]+1ll*sumf[edge[i].v]*ret)%mod;
            sumg[x]=(sumg[x]+1ll*sumg[edge[i].v]*ret+1ll*tmp*sumf[edge[i].v])%mod;
        }
    }
}
void getans(int val,int L,int R){
    for(int i=1;i<=n;i++)f[i]=g[i]=sumf[i]=sumg[i]=0;
    dfs(1,0,L,R);
    for(int i=1;i<=n;i++)ans1=(ans1+1ll*f[i]*val)%mod,ans2=(ans2+1ll*g[i]*val)%mod;
}
int qpow(int a,int b){
    int ans=1;
    while(b){
        if(b&1)ans=1ll*ans*a%mod;
        a=1ll*a*a%mod;
        b>>=1;
    }
    return ans;
}
int pos[1010],cnt,x[210],Y1[210],Y2[210];
int lage(int n,int x[],int y[]){
    int ans=0;
    for(int i=0;i<cnt;i++){
        int up=1,down=1;
        for(int j=0;j<cnt;j++){
            if(i!=j)up=1ll*up*(n-x[j]+mod)%mod,down=1ll*down*(x[i]-x[j]+mod)%mod;
        }
        ans=(ans+1ll*up*qpow(down,mod-2)%mod*y[i])%mod;
    }
    return ans;
}
int main(){
    scanf("%d%d",&n,&K);int mx=0;pos[0]++;
    for(int i=1;i<=n;i++){
        scanf("%d%d",&l[i],&r[i]);
        pos[++pos[0]]=l[i];pos[++pos[0]]=max(0,l[i]-K);
        pos[++pos[0]]=r[i];pos[++pos[0]]=max(0,r[i]-K);mx=max(mx,r[i]);
    }
    pos[++pos[0]]=mx+1;
    sort(pos+1,pos+pos[0]+1);pos[0]=unique(pos+1,pos+pos[0]+1)-pos-1;
    for(int i=1;i<n;i++){
        int u,v;scanf("%d%d",&u,&v);
        add(u,v);add(v,u);
    }
    for(int i=1;i<pos[0];i++){
        int L=pos[i],R=pos[i]+K;
        for(cnt=0;cnt<n+3;cnt++){
            if(pos[i]+cnt==pos[i+1])break;
            getans(1,L,R);L++;getans(mod-1,L,R);R++;
            x[cnt]=pos[i]+cnt;Y1[cnt]=ans1;Y2[cnt]=ans2;
        }
        if(pos[i]+cnt<pos[i+1]){
            ans1=lage(pos[i+1]-1,x,Y1);ans2=lage(pos[i+1]-1,x,Y2);
        }
    }
    printf("%d\n%d\n",ans1,ans2);
    return 0;
}

标签:210,省选,题解,int,edge,sumg,sumf,联考,mod
From: https://www.cnblogs.com/gtm1514/p/17122170.html

相关文章

  • NOIP2015 普及组 推销员题解
    原题链接给定一个数轴,数轴上有一些点,第\(i\)个点离起点的距离是\(S_i\),取走它要消耗\(A_i\)的代价,同时在数轴上每移动一格要\(1\)的代价,路线只能从数轴......
  • CSP2022 假期计划 题解
    给你一张\(n\)个点,\(m\)条边的无向图,每个点有点权,要求你在图中选出\(A\),\(B\),\(C\),\(D\)四个点,使得\(1\rightarrowA\rightarrowB\rightarrowC\righ......
  • DTOJ 2023.02.11 测试 题解
    DTOJ2023.02.11测试题解2023省选模拟Round#12\(100+8+50=158\)还行T2想到了,但是没写,我觉得写了也不一定写得出来,挺妙的T1题意http://59.61.75.5:18018/p/545......
  • 读者最需要什么样的题解
    哈哈,其实还是鲜花,主要是看到\(\text{f}\color{red}{\text{eecle6418}}\)的这篇题解有感而发,当然我自己写的题解也很抽象,需要改正。当然这里的写题解是指主动打算写一......
  • 小孩召开法 题解
    开题之前の一些废话:小孩召开法,旦写一北砬。梦厷停留在,破了大式様。——龚诗锋《炄勺,砒》小孩。又是我很不会的排列计数。而且神题。久仰大名。现在是2月13日......
  • ARC120C Swaps 2 题解
    好难啊,会也不会设\(a_i=x,a_{i+1}=y\),那么交换后\(a_i=y+1,a_{i+1}=x-1\),发现交换后就是\(a_i+i\)和\(a_{i+1}+i+1\)这两个值进行了交换。那就把所有\(a_i\)变成......
  • 青龙面板调试运行代码时打印语句可能不执行的问题解决
    记录一次用青龙面板调试调用chatGPT的API时发现的一个问题:脚本在调试运行时,有可能会不显示部分打印语句的,例如node.js(python也有这种情况),如下图:关于为什么会出现此问题......
  • 省选联测32
    nnd考不动了,脑子不转了已经A.光明正解做法是\(O(n)\)的,长剖一下,在链上差分贡献,但是貌似常数极大,不知道为啥开六秒。赛时写的是两个log的二分加启发式,实际表现和\(O(n)\)......
  • lg9018题解
    #include<bits/stdc++.h>usingnamespacestd;#defineN2000010#defineintlonglong#definemo1000000007intjc[N],ij[N],n,a[N];intc(inty,intx){ if(y<x)......
  • 【题解】ARC153 A-D
    怎么感觉ARC困难的永远是B题[惊恐]A.AABCDDEFE题目分析:完全可以把相等的位置合并在一起,这样就剩下了\(6\)个位置,然后就转化为了第\(N\)小的六位数是多少,这应该......