2019杭電多校第一場

2021-09-25 14:02:09 字數 4465 閱讀 9472

dp[

i][j

][k]

[t

]dp[i][j][k][t]

dp[i][

j][k

][t]

表示0 ,1

,2,3

0,1,2,3

0,1,2,

3出現的位置排序後為i,j

,k,t

i,j,k,t

i,j,k,

t的方案數

列舉第t+1

t+1t+

1位的情況進行轉移

對於限制情況,固定右端點,暴力列舉所有狀態,把所有非法狀態清零

#include

#include

#include

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

#define mp make_pair

using namespace std;

int n,m,res,i,l,r,x,t,tt,j,k,p;

int f[

105]

[105][

105][2

];vectorint,

int>> d[

105]

;int

main()

memset

(f,0

,sizeof

(f))

; f[0]

[0][

0][0

]=1;

fo(t,

1,n)

fo(i,

0,t)

fo(j,i,t)

fo(k,j,t)

for(p =

0;p < d[t]

.size()

; p++)}

res =0;

fo(i,

0,n)

fo(j,i,n)

fo(k,j,n)

res =

(res + f[i]

[j][k]

[n&1])

% mod;

cout<}return0;

}

從近到遠不斷求出每輛車的速度函式

顯然每輛車的速度是乙個階梯形(每次撞上前一輛車速度都會變小)

如何根據第i

ii輛車的影象得到i+1

i+1i+

1輛車的影象?

先畫出一條水平線表示初始速度,然後求什麼時候兩條曲線之間的面積等於兩車初始距離(即什麼時候追上),之後的速度影象一致

當然這個面積也可以是負數(表示前車開始過快,距離拉大)

時間複雜度為o(n

)o(n)

o(n)

記錄像象的「階梯拐點」(速度變化點)即可

#include

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

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

#define n 5000000

using namespace std;

int n,i,base,head,flag;

int l[n]

,s[n]

,v[n]

,p[n]

;double t[n]

;double d,dd;

intmain()

d -=(t[head+1]

- t[head])*

(v[i]

- p[head]);

head++;}

if(flag ==1)

dd = d /

(v[i]

- p[head]);

t[head]

+= dd;

head--

; t[head]=0

; p[head]

= v[i];}

d = s[n]

;while

(d >

(t[head+1]

-t[head]

)* p[head]

) dd = d / p[head]

; t[head]

+= dd;

printf

("%.10lf\n"

,t[head]);

}return0;

}

先保留所有最短路的邊,即滿足du−

dv=w

d_u-d_v=w

du​−dv

​=w的邊,然後跑最小割

暴力列舉每一位的字母,合法的依據是字尾能否滿足條件

#include

#include

#include

#include

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

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

#define n 500000

using namespace std;

int n,i,j,t,head,nextpos,flag,suffix;

char ch[n]

;queue<

int> pos[30]

;int a[n]

,l[30

],r[30]

,cnt[n][30

];queue<

int> res;

int resflag;

intmain()

if(t < suffix)}if

(flag)

continue;if

(l[i]

) l[i]

--; r[i]--;

res.

push

(i);

head = nextpos;

resflag =1;

break;}

if(resflag ==0)

}if(resflag ==1)

while

(!res.

empty()

) cout<}return0;

}

問題轉化為能否用一條直線分開兩類點

這個問題等價於兩個凸包是否相交

兩兩比較兩個凸包上的邊是否相交即可

注意先判斷所有點的凸包,特判內含的情況

#include

#include

#include

#include

using namespace std;

const

double eps=

1e-10

;const

int maxn=

300;

struct point pnt[maxn]

,pnt1[maxn]

,pnt2[maxn]

,res1[maxn]

,res2[maxn]

;bool mult

(point sp,point ep,point op)

bool operator <

(const point &l,

const point &r)

intgraham

(point pnt,

int n,point res)

len=top;res[

++top]

=pnt[n-2]

;for

(int i=n-

3; i>=

0; i--

)return top;

}bool inter

(point a,point b,point c,point d)

intmain()

else}if

(n==

1||n==2)

if(n1==n||n2==n)

int m=

graham

(pnt,n,res1)

;int cnt=0;

for(

int i=

0;i(res1[i]

.id==

1) cnt++;if

(cnt==

0||cnt==m)

int m1=

graham

(pnt1,n1,res1)

;int m2=

graham

(pnt2,n2,res2)

;int flag=0;

for(

int i=

0;i<=m1-

1;i++)}

if(flag)

break;}

if(flag) cout<<

"infinite loop!"

"successful!"

<}return0;

}

2019 杭電多校(第一場)

題目 1002 operation 線性基 題意給你n個數 兩個操作,查詢l r區間異或最大值 在陣列最後麵加一數 思路維護兩個陣列 1 b i j 儲存a 1 到a i 之間的第j位線性基。2 pos i j 儲存最大的l a l 使得b i j 有值。對於每一次詢問 l,r 如果pos r j ...

2019杭電多校第一場

從右到左分別為0 n輛車,每輛車有長度l,起始位置s和速度v,0座標在左邊,不能超車,單車道,問0號車到達0座標的最短時間。最短時間考慮二分時間,然後按這個時間從左邊第一輛車開始依次計算最終位置,最後判斷0號車的位置即可。include using namespace std const int n...

2019 杭電多校 第一場

2019 multi university training contest 1 給定包含 n 個數的序列,m 個詢問。詢問有兩種操作,操作 0 表示在陣列最後新增乙個新元素,操作 1 表示查詢區間 l,r 的子集的異或最大值。線性基 貪心一條路上有 n 1 輛車。第 i 輛車的長度為 l i 離終...