JZWC Day2 題解 總結

2021-07-09 14:20:16 字數 4885 閱讀 3683

果然說day1會水成狗,day2**成狗,這次改題改的我都沒有心情好好玩耍了……

附上題解

description

input

第一行輸入乙個正整數t 表示資料組數。每組資料的第一行是乙個整數m,接下來m 行每行五個整數ai, bi, ci, di, li,保證0 <= ai, bi < i, 0<= li<= 10^9,ci, di 存在。

output

對於每組詢問輸出m 行。第i 行輸出ti 的權值。答案可能很大,請對10^9 + 7 取模後輸出。

sample input

1

2 0 0 0 0 2

1 1 0 0 4

sample output

2

28

data constraint

對於30% 的資料,m <= 8

對於60% 的資料,m <= 16

對於100% 的資料,1 <= m<= 60,t<= 100

solution

神題一道,改了兩天。

首先,我們要知道,這樣建出的樹可能非常大,是不能用普通的方法表示的。

用ans[i]來表示ti的答案,cout[i]表示ti的節點個數,all(x,i)表示tx中所有的點到i這個點的距離和,因為這棵樹由兩棵樹組成,我們可以推出如下公式:

ans[i]=ans[a[i]]+ans[b[i]]+cout[a[i]] * cout[b[i]] * l[i]+all(a[i],c[i]) * cout[b[i]]+all(b[i],d[i])*cout[a[i]];

然後我們思考如何求all(x,i)。發現上面我們已經把乙個問題分成了許多子問題,那麼我們能不能再把all分開來求呢?

很明顯是可以的。設to(x,i,j)表示tx中,點i到點j的距離,則

若l為組成x的左子樹,r為右子樹,

(1)i存在於l中

all(x,i)=all(r,d[x])+all(l,i)+(l[x]+to(l,i,c[x]))*cout[r];

(2)i存在於r中

all(x,i)=all(l,c[x])+all(r,i)+(l[x]+to(r,i,d[x]))*cout[l];

有了上面的經驗,我們也可以吧to(x,i,j)分開來求,詳細見**。

然後,我們可以寫記憶化搜尋,這樣每一次to的複雜度是o(n)的,每一次all都要呼叫一次to,所以複雜度是o(n^2)。

總複雜度為o(n^3)

code

#include

#include

#include

#define fo(i,a,b) for(int i=a;i<=b;i++)

#define ll long long

#define mo 1000000007

#define n 65

using

namespace

std;

map,ll> h[n];

map h1[n];

struct note

}f[n];

ll cout[n],ans[n],c[n];

ll ty,n;

ll to(ll z,ll x,ll y)

ll all(ll x,ll y)

int main()

}}

description

有n個人,每一輪隨機選擇沒有出局的人乙個人出局,然後剩下的人受到一次攻擊,每個人被攻擊就有 p的概率淘汰,求當k=0..n-1時,每個人受到k次攻擊然後出局的概率是多少,答案在模258280327 意義下。注意,出局不等於淘汰。

input

第一行輸入乙個正整數t 表示資料組數。

對於每一組資料輸入僅一行三個數n, x, y,表示在這組資料中有n 個人參賽,p = x/y。保證y 和258280327 互質。

output

對於每組資料,輸出一行n 個整數,表示對於k = 0到n - 1 的概率在模258280327 意義下的值。

sample input

2

3 40 100

9 32 1049

sample output

172186885 92980918 16529941

229582513 163885050 39458156 102374877 116777758 216371874 55544199 95860736 8136787

data constraint

對於60% 的資料,n <=100

對於100% 的資料,n <= 2* 10^3,1 <= t <= 5,0<= x < y <= 10^9

solution

沒什麼好說的了,首先你要理解清楚題意,然後再看懂樣例,然後你就大概會做了。

因為它是隨機選人出局,我們把它變成按順序選人出局,對於每個k,所有人出局的總概率是不變的。而題目描述的每個人出局的概率是相等的,所以按我們只需要做一次線性的dp,算出答案,然後取個平均數就行了。

code

#include

#include

#define fo(i,a,b) for(int i=a;i<=b;i++)

#define ll long long

#define n 2005

#define mo 258280327

using namespace std;

int ty,n;

ll x,y,f[n][n],ans,p[n];

ll mi(ll x,ll y)

return z;

}int main()

fo(i,0,n-1)

printf("\n");

}

}

description

定義一些字串,s1=』a』,s2=』b』,si=si-1+si-2,給出n,m,求sn的前m個字元形成的字串中,最長的相等前字尾的長度。如,ababa為3。

input

第一行輸入乙個正整數t 表示資料組數。

對於每組資料,第一行是兩個整數n;m。保證1<= m <=|sn|

output

對於每組資料,輸出乙個整數表示答案。答案可能很大,你只需要輸出模258280327 後的答案。

sample input

2

4 3

5 5

sample output

1

2

data constraint

對於30% 的資料,n <= 20

對於60% 的資料,n <= 60

對於100% 的資料,n <= 10^3,1 <= t <= 100

solution

首先,你得打個表,然後找規律。然後你就會發現,設k為最小的sk使得|sk|>m+1,那麼答案就是m-|sk-2|,上高精度就行了。證明自行腦補,意會即可。

code

#include

#include

#include

#define fo(i,a,b) for(int i=a;i<=b;i++)

#define fd(i,a,b) for(int i=a;i>=b;i--)

#define n 1005

#define maxn 100000000

#define mo 258280327

#define ll long long

using

namespace

std;

struct notef[n],m,one;

note add(note x,note y)

if (z.a[z.l+1]) z.l++;

return z;

}note dec(note x,note y)

if (!z.a[z.l]) z.l--;

return z;

}bool big(note x,note y)

char s[n];

int ty,n,l,r,mid,ten[9];

ll ans;

int main()

if (k) m.a[++m.l]=k;

note p=add(m,one);

while (l2;

if (big(f[mid],p)) r=mid;else l=mid+1;

}l-=2;

m=dec(m,f[l]);ans=0;

fd(i,m.l,1) ans=(ans*maxn%mo+m.a[i])%mo;

printf("%lld\n",ans);

}}

果然跪了呀!整場比賽都被第二題的題意搞得不要不要的,只打了第三題的暴力。看來策略還是有問題,不要死磕一道題,尤其是那麼kd的題!

總結 題解(2)

實際上,我乙個大周總結的東西並不多,這個大周的刷題量還算可以,大部分就在鞏固以前的知識,bfs和dfs也破天荒地地懂了一些 我也搞不懂我是怎麼聽懂的 dp就比較蒙蔽了 我也不知道為什麼,dp一直是很蒙蔽,dfs和bfs也不是很熟,所以,我接著寫某些題的題解,我還想說的是,千萬不能手賤 讀入a,b,c...

NOIPTG A組總結 T2題解

這是個慘烈的日子,讓我貼一貼成績。嗯。這就tm很尷尬了。話說我二十分還能拿個rank4。醉了 t1 world tour cf666b 667d 題意 給你一些單向邊,讓你求出四個點,使得經過這四個點的路徑盡可能的長 兩點之間走最短路徑,四個點不能重複,但是經過路徑可以 直接暴力spfa求出最遠的兩...

SQL題解總結

1.按排名取奇數 解題思路 判斷是否是奇數的依據 一組n個資料 a 中的某乙個數,a組資料中有m個數大於等於這個數,排序後則這個數的序號是m 題目要取排名為奇數的資料,字母排序規律是a b c.但是ascii碼實際上a答案 select e1.first name from employees e1...