「PKUSC2018」星際穿越 (70分做法)
阿新 • • 發佈:2018-06-16
期望 成功 習慣 ons 由於 nbsp inpu 開始 long long
Submit: 27 Solved: 11
[Submit][Status][Discuss]
第一行一個正整數n,表示星球的個數。
第二行n-1個正整數,第i個正整數為Li+1,
表示編號在[Li+1,i]區間內所有星球已經與編號為i+1的星球取得了聯系,並且可以通過花費1單位進行彼此的傳輸。保證Li+1≤i
第三行一個正整數q,表示詢問組數。
接下來q行,每行三個數字Li,Ri,xi,表示在[Li,Ri]這個區間中等概率選擇一個星球y,dist(xi,y)的期望。
保證Li<Ri<xi,n,q≤3×10^5
7
1 1 2 1 4 6
5
3 4 6
1 5 7
1 2 4
1 2 6
1 3 5
13/5
3/2
2/1
1/1 我本沒有什麽平時做題也寫暴力的習慣,只是填一下考場上的坑罷了。。。。 pkusc day2的時候一開始就去懟T3計算幾何,雖然思路和正解一樣但無奈寫掛了2333,最後剩2h給T1和T2,暴力都沒打全,GG。 所以就有T1大眾分70我45的奇特景觀。。。。。。 70分的話,只需要發現最優策略只能最多向右走一步(並且是第一步),所以我們可以 O(N^2) 掃一遍,預處理出來一個數組 f[i][j] 表示 點i走j步能走到左端最遠的那個點,然後用這個更新一下dis[i][j](兩兩點之間的最短路),做一個前綴和,直接回答詢問即可。。。。
5371: [Pkusc2018]星際穿越
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 27 Solved: 11
[Submit][Status][Discuss]
Description
有n個星球,它們的編號是1到n,它們坐落在同一個星系內,這個星系可以抽象為一條數軸,每個星球都是數軸上的一個點, 特別地,編號為i的星球的坐標是i。 一開始,由於科技上的原因,這n個星球的居民之間無法進行交流,因此他們也不知道彼此的存在。 現在,這些星球獨立發展出了星際穿越與星際交流的工具。 對於第i個星球,他通過發射強力信號,成功地與編號在[Li,i-1]的所有星球取得了聯系(編號為1的星球沒有發出任何信號), 取得聯系的兩個星球會建立雙向的傳送門,對於建立了傳送門的兩個星球u,v,u上的居民可以花費1單位時間傳送到v, v上的居民也可以花費1單位時間傳送到u,我們用dist(x,y)表示從編號為x的星球出發,通過一系列星球間的傳送門, 傳送到編號為y的星球最少需要花費的時間。 現在有q個星際商人,第i個商人初始所在的位置是xi,他的目的地是[Li,Ri]中的其中一個星球,保證Li<Ri<xi。 他會在這些星球中等概率挑選一個星球y(每個星球都有一樣的概率被選中作為目的地), 然後通過一系列星球的傳送門,花費最少的時間到達星球y。 商人想知道他花費的期望時間是多少?也就是計算∑dist(xi,y)/(Ri-Li+1),其中y<=Li<=RiInput
Output
對於每組詢問,註意到答案必然是一個有理數,因此以p/q的格式輸出這個有理數,要求gcd(p,q)=1 如果答案為整數m,輸出m/1Sample Input
1 1 2 1 4 6
5
3 4 6
1 5 7
1 2 4
1 2 6
1 3 5
Sample Output
3/213/5
3/2
2/1
1/1 我本沒有什麽平時做題也寫暴力的習慣,只是填一下考場上的坑罷了。。。。 pkusc day2的時候一開始就去懟T3計算幾何,雖然思路和正解一樣但無奈寫掛了2333,最後剩2h給T1和T2,暴力都沒打全,GG。 所以就有T1大眾分70我45的奇特景觀。。。。。。 70分的話,只需要發現最優策略只能最多向右走一步(並且是第一步),所以我們可以 O(N^2) 掃一遍,預處理出來一個數組 f[i][j] 表示 點i走j步能走到左端最遠的那個點,然後用這個更新一下dis[i][j](兩兩點之間的最短路),做一個前綴和,直接回答詢問即可。。。。
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=5005; int mn[maxn],L[maxn],n,Q,f[maxn][maxn],d[maxn][maxn],a,b,c; int gcd(int x,int y){ return y?gcd(y,x%y):x;} inline void prework(){ mn[n+1]=n+1; for(int i=n;i;i--) mn[i]=min(mn[i+1],L[i]); for(int i=1;i<=n;i++) f[i][2]=mn[i+1],f[i][0]=i,f[i][1]=L[i]; for(int i=2,k,j;i<=n;i++){ k=i-1; for(j=1;f[i][j]>1;j++) for(;k>=f[i][j];k--) f[i][j+1]=min(f[i][j+1],L[k]),d[i][k]=j; for(;k;k--) d[i][k]=j; } for(int i=2;i<=n;i++) for(int j=1;j<i;j++) d[i][j]+=d[i][j-1]; } inline void solve(){ scanf("%d",&Q); while(Q--){ scanf("%d%d%d",&a,&b,&c); c=d[c][b]-d[c][a-1]; a=b-a+1,b=gcd(a,c); a/=b,c/=b; printf("%d/%d\n",c,a); } } int main(){ memset(f,0x3f,sizeof(f)); scanf("%d",&n),L[1]=1; for(int i=2;i<=n;i++) scanf("%d",L+i); prework(); solve(); return 0; }
「PKUSC2018」星際穿越 (70分做法)