6392. [2019年10月26日] NOIP2019アナログゾンビ

タイトル説明


問題の解決策

質問を叫びましたしかし、問題どのようにファンに、このような解決策
問題に対する異なるアプローチ及び溶液(理解)を考慮
第ゾンビの離散を、同じ時間チン(英)ポイントサイズ
(これは、それぞれの場合に見出され得るのみ一度だけカウントされる)
の計算方式が完全に占有され、その後、1 -プログラム/確率
による大きさが決定されるので、最終的に接続されていないブロックに分割され、そしてブロックのみゾンビが存在する
ブロックの数が占有ゾンビの数で定義する
[I] [X](F提供 X > 0)は、iをルートとするサブツリーを示しているブロック番号iがxは点
F [J]のために、次には、[Y]( j∈son[i]は、J> 0) 以下の転写:
①XY =
F [J ] [Y] (I介してXゾンビ- jはプログラムの数である) - > F [i]は、[ X]
、同じブロック内のゾンビのみ1ブロック内のxとy、ブロックは、ために通信する必要があります
②X <Y
F [J] [Y]
(I無しYゾンビ- jはプログラムの数である) - > F [I] [x]は
、xおよびyは接続できないように、x及びyは、同じブロックに含まれていない、すなわち、他の点(I)に行くことができない、より大きな(y)をゾンビ
と保証するために、Y jの存在を、Xが存在しない場合、以下の理由
③X-> Y
F [J] [Y] *(Xゾンビi--無しj)はプログラムの数である- > F [i]が[ X]
原因&スコープ上掲

F初期値[I] [X] = [X> = H [I]](X> 0)

制限②③の:
のようなことを確実にする点xまでゾンビのちょうど存在iはブロックの最も浅い点であり
iおよびFA [i]が切断されたときことを保証私はXサブツリー葉、ブロックI息子が切断確保するためにブロック離れたブロックの外側のxをされていない、ブロックは、xとなるように存在しなければなりません

OはO(n ^ 2)に最適化された(N ^ 3)、接頭辞と接尾辞の時間複雑

コード

#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;
}

おすすめ

転載: www.cnblogs.com/gmh77/p/11756104.html