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 離終...