前言
已经高三了,但是还是想玩一下,抽空写点题目,顺便记录一下。
【前情提要:本文的撰写具有滞后性,因此流失了大量细节。】
2023.9.16 2023.9.16 2023.9.16
初赛,完善程序做得稀烂,好在 60 + 60+ 60+ 还是过线了。真不敢相信今年浙江线会这么低,只有 50.5 p t s 50.5 \rm{pts} 50.5pts。
2023.9.29 2023.9.29 2023.9.29
呃,高三牲的国庆只有 3 3 3 天。问老师要了题目,打长乐的模拟赛。
T1
\texttt{T1}
T1 一看
1
0
9
10^9
109 的数据范围加
1
0
6
10^6
106 的询问就猜测是推出式子加上矩阵快速幂优化。手玩小数据推了半天,还很不要脸的用了一下
OEIS
\texttt{OEIS}
OEIS,发现
f
n
=
f
n
−
1
+
f
n
−
3
+
1
f_n = f_{n - 1} + f_{n - 3} + 1
fn=fn−1+fn−3+1,所以就有了一个
4
×
4
4 \times 4
4×4 的矩阵:
[
f
[
n
]
f
[
n
−
1
]
f
[
n
−
2
]
1
]
=
[
1
0
1
1
1
0
0
0
0
1
0
0
0
0
0
1
]
n
−
3
×
[
f
[
n
−
1
]
f
[
n
−
2
]
f
[
n
−
3
]
1
]
\left[ \begin{array}{ccc}f[n]\\f[n - 1]\\f[n - 2]\\1 \end{array} \right] = \left[ \begin{array}{ccc}1\ 0 \ 1 \ 1 \\ 1 \ 0 \ 0 \ 0 \\ 0 \ 1 \ 0 \ 0 \\ 0 \ 0 \ 0 \ 1 \end{array} \right] ^ {n - 3} \times \left[ \begin{array}{ccc}f[n - 1]\\f[n - 2]\\f[n - 3]\\1 \end{array} \right]
f[n]f[n−1]f[n−2]1
=
1 0 1 11 0 0 00 1 0 00 0 0 1
n−3×
f[n−1]f[n−2]f[n−3]1
算了一下时间复杂度是 O ( T × 4 3 × log n ) O(T \times 4^3 \times \log n) O(T×43×logn),好像数据有点大,可能会被卡常,但是没管了先做后面的。
T2 \texttt{T2} T2 似乎是个简单题,就是求 A A A 中有多少段和 B B B 的长度相同且含 1 1 1 的个数相同。由于题目限制了询问串的总长,所以充分利用好根号这一分界线,小于的用记忆化的方式去算,大的直接暴力,时间复杂度 O ( n L ) O(n \sqrt{L}) O(nL)。
T3 \texttt{T3} T3 染色,大概是要 dp \texttt{dp} dp,但是似乎不会。写了一个暴力外加颜色均相同的这一档的递推。
T4 \texttt{T4} T4 将 n n n 个数均分到 k k k 个集合中,保证每个集合中元素互异。设第 i i i 个集合中的极差为 s i s_i si,求 min ( ∑ i = 1 k s i ) \min (\sum_{i = 1}^{k} s_i) min(∑i=1ksi)。这个暴力看上去也很难打,所以陷入沉思。就在我一直盯着 n ≤ 70 n \le 70 n≤70 的数据范围上时,突然想到了一种乱搞做法:就是每次打乱这 n n n 个数,然后按顺序塞入 k k k 个集合中,若所有集合合法,那么更新答案。不断循环最后加上一个卡时就行。试了一下能过样例,真棒!
预计得分: 80 + 100 + 30 + ? ? ? 80 + 100 + 30 + ??? 80+100+30+???;
实际得分: 60 + 100 + 20 + 60 = 240 pts 60 + 100 + 20 + 60 = 240 \texttt{pts} 60+100+20+60=240pts。
震惊,乱搞做法竟然获得了 60 60 60 的高分,这是好的。但是, T1 \texttt{T1} T1 被多卡了 20 20 20,以及 T3 \texttt{T3} T3 写了好长的递推的 10 pts 10 \texttt{pts} 10pts 好像错了没拿到分数。看了一下排名 rk 4 \texttt{rk 4} rk 4 还不错。
看了题解,第一题是对 4 3 4^3 43 的矩阵转移的优化,倍增预处理然后在询问里用 1 × 4 1 \times 4 1×4 和 4 × 4 4 \times 4 4×4 的矩阵更新。后面两题嘛,看了题解还是实现不出来 qwq。
2023.9.30 2023.9.30 2023.9.30
T1 \texttt{T1} T1 简单的模拟,本来想着线段树优化求和,但马上发现差分就行了,半小时内就码完了这题。好像还抢到了一血来着。
T2 \texttt{T2} T2 竟然做过,是 The Shortest Statement,最短路加最小生成树的好题!但是数据范围有些差异,赛时过于高兴的复制了当时的代码,没仔细看,所以最后因为数组越界 100 → 40 100 \to 40 100→40。
T3 \texttt{T3} T3 又是一道考察冒泡排序的深度理解的题目,很容易想到按照奇偶位处理,但是发现复杂度怎么搞都是 O ( n m log n ) O(nm \log n) O(nmlogn),最后交了暴力上去。赛后订正发现题解的方法很妙,用桶记录数字,然后奇数 + 1 +1 +1,偶数 − 1 -1 −1,这样就可转换为数据结构维护极值。
T4 \texttt{T4} T4 动归,转移方程很好列:
d p i = max { d p j ∣ a i ≥ a j , 0 ≤ j ≤ i − 1 − ( i − j ) ( i − j − 1 ) 2 } + a i dp_i = \max \{dp_{j|a_i \ge a_j,0 \le j \le i - 1} - \dfrac{(i - j)(i - j - 1)}{2}\} + a_i dpi=max{dpj∣ai≥aj,0≤j≤i−1−2(i−j)(i−j−1)}+ai,答案的更新是 a n s = max ( a n s , d p i − ( n − i + 1 ) ( n − i ) 2 ) ans = \max \left (ans,dp_i - \dfrac{(n - i + 1)(n - i)}{2}\right) ans=max(ans,dpi−2(n−i+1)(n−i))。然后不太会斜率优化以及不太会 a i ≥ a j a_i \ge a_j ai≥aj 的处理,所以就实现了一个 O ( n 2 ) O(n^2) O(n2) 的朴素 dp \texttt{dp} dp。由于我并没有处理负数的情况,但是好像部分分的数据有误,所以我爆灵了。
最后得分: 100 + 40 + 30 + 0 = 170 100 + 40 + 30 + 0 = 170 100+40+30+0=170,排名 rk 15 \texttt{rk 15} rk 15。本来应该是: 100 + 100 + 30 + 20 = 250 100 + 100 + 30 + 20 = 250 100+100+30+20=250 的呜呜呜……
2023.10.01 2023.10.01 2023.10.01
T1 \texttt{T1} T1 稍作分析就发现这个概率并没什么实际的用处,能到达与根距离为 k k k 的结点的期望为 2 − k 2^{-k} 2−k。直接遍历所有的根求解为 O ( n 2 ) O(n^2) O(n2),容易想到换根 dp \texttt{dp} dp, f u = 2 s z u − 1 + ∑ v ∣ s o n u 2 s z u − s z v − 1 f v f_u = 2^{sz_u - 1} + \sum_{v \mid son_u} 2^{sz_u - sz_v - 1} f_v fu=2szu−1+∑v∣sonu2szu−szv−1fv,时间复杂度就变为 O ( n ) O(n) O(n)。自己实现的时候直接处理了 2 − k 2^{-k} 2−k 算期望,和标程的转移方程略有不同。
T2 \texttt{T2} T2 直接构造若干个完全图,一个完全图的三元环数为 C k 3 = k ( k − 1 ) ( k − 2 ) 6 C_k^3 = \dfrac {k(k - 1)(k - 2)}{6} Ck3=6k(k−1)(k−2)。因此从 500 500 500 开始向 1 1 1 开始遍历即可。简单题,并拿到了一血。
T3 \texttt{T3} T3 赛时在贪心还是动规之间徘徊。还是分析不到位,最后打了个暴力交上去,但是 WA \texttt{WA} WA 了。
T4 \texttt{T4} T4 不知怎的,写了一个模拟,也 WA \texttt{WA} WA 了。
最后得分: 100 + 100 + 0 + 0 = 200 100 + 100 + 0 + 0 = 200 100+100+0+0=200,排名 rk 10 \texttt{rk 10} rk 10。
2023.10.15 2023.10.15 2023.10.15
打洛谷上的模拟赛,打得有点废, 100 + 8 + 25 + 0 = 133 100 + 8 + 25 + 0 = 133 100+8+25+0=133。
T1 \texttt{T1} T1 想的 dp \texttt{dp} dp 一直假,直到机房大佬的点拨以后才勉强写出来。反正花费了很多很多时间。赛后看题解,发现 ST \texttt{ST} ST 表页行,反正赛时啥也不行。
T2 \texttt{T2} T2 暴力,然后润。赛后补题,其实也蛮好想的,就是基于二进制位的树上 dp \texttt{dp} dp,设 g [ u ] [ i ] [ 0 / 1 ] g[u][i][0/1] g[u][i][0/1] 表示以 $u $为根的子树内,所有断边方案中价值在二进制下第 i i i 位为 0 / 1 0/1 0/1 的不与 u u u 相连的联通块的价值乘积的和.
T3 \texttt{T3} T3 暴力大分讨,然后润。正解是区间 dp \texttt{dp} dp,时间复杂度 O ( T n 3 ) O(Tn^3) O(Tn3),看题解吧,思路就不写了。
T4 \texttt{T4} T4 没看,直接润。
2023.10.21 2023.10.21 2023.10.21
比赛日! rp++ \texttt{rp++} rp++!
T1 \texttt{T1} T1 水题,直接暴力搜索,然后过大样例。
T2 \texttt{T2} T2 字符串消消乐,想了半天只会 O ( n 3 ) O(n^3) O(n3) 的区间 dp \texttt{dp} dp,之后一直没有进展。害,其实出考场才发现 O ( n 2 ) O(n^2) O(n2) 的做法也蛮好想的。当然,正解是线性做法,发现从 1 1 1 到 n n n 维护栈序列时,若对于某个时刻 l l l 和某个时刻 r r r,两种时刻的栈序列完全相同,那么说明子串 ( l + 1 , r ) (l+1,r) (l+1,r) 一定是可消除。
T3 \texttt{T3} T3 大模拟,写了半天放弃了最后一题,最后因为看错一丢丢题干,喜提 0 pts 0 \texttt{ pts} 0 pts。不说了,赛后写了 3.02 KB 3.02 \texttt{KB} 3.02KB 苟过了。放个代码纪念一下:
#include <bits/stdc++.h>
#define init(x) memset (x,0,sizeof (x))
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
using namespace std;
const int MAX = 1e5 + 5;
const int MOD = 1e9 + 7;
int n;ll p;//所有变量的内存指针
struct ele //定义一个变量
{
ll len,ali_len;//占据空间 对齐要求
string ty,name;//类型 变量名称
} ;
struct stct
{
ll len,ali_len;
string name;
vector <ele> v;//记录结构体内的每一个变量
stct () {len = ali_len = 0;name = "";v.clear ();}
} tot;//记录所有的变量的一个大结构体
map <string,int> bs;//4 个基本类型
map <string,stct> ext;//自定义类型
void init_basic ();
void calc (ll &p,ll x);
void op_one ();
void op_two ();
void op_three ();
void op_four ();
int main ()
{
// freopen (".in","r",stdin);
// freopen (".out","w",stdout);
cin>>n;init_basic ();
for (int i = 1;i <= n;++i)
{
int ty;cin>>ty;
if (ty == 1) op_one ();
if (ty == 2) op_two ();
if (ty == 3) op_three ();
if (ty == 4) op_four ();
}
return 0;
}
void init_basic () {bs["byte"] = 1;bs["short"] = 2;bs["int"] = 4;bs["long"] = 8;}
void calc (ll &poi,ll ali) {poi = ceil ((long double) poi / ali) * ali;}//当前地址 对齐要求
//tmp 表示新的结构体 nw 表示新的变量
void op_one ()
{
int k;stct tmp;cin>>tmp.name>>k;
for (int i = 1;i <= k;++i)
{
ele nw;cin>>nw.ty>>nw.name;
if (bs[nw.ty]) nw.len = nw.ali_len = bs[nw.ty];//基本类型
else nw.len = ext[nw.ty].len,nw.ali_len = ext[nw.ty].ali_len;//自定义类型
tmp.ali_len = max (tmp.ali_len,nw.ali_len);tmp.v.push_back (nw);//计算对齐要求 在结构体中加入变量
calc (tmp.len,nw.ali_len);tmp.len += nw.len;//地址偏移的处理 长度更新
}
calc (tmp.len,tmp.ali_len);
ext[tmp.name] = tmp;//加入一个新的结构体
printf ("%lld %lld\n",tmp.len,tmp.ali_len);
}
void op_two ()
{
ele nw;ll ans = 0;cin>>nw.ty>>nw.name;
for (ele x : tot.v) calc (ans,x.ali_len),ans += x.len;
calc (ans,bs[nw.ty] ? bs[nw.ty] : ext[nw.ty].ali_len);
tot.v.push_back ({bs[nw.ty] ? bs[nw.ty] : ext[nw.ty].len,bs[nw.ty] ? bs[nw.ty] : ext[nw.ty].ali_len,nw.ty,nw.name});//将新变量加入的总的结构体中
printf ("%lld\n",ans);
}
void op_three ()
{
string s;stct tmp = tot;ll ans = 0;cin>>s;
for (int i = 0,j;i < s.size ();i = j + 1)
{
j = i;
while (j < s.size () && s[j] != '.') ++j;
string nw = s.substr (i,j - i);//以 . 分隔层层取出变量
for (ele x : tmp.v)
{
calc (ans,x.ali_len);
if (x.name == nw) {tmp = ext[x.ty];break;}//层层深入
ans += x.len;
}
}
printf ("%lld\n",ans);
}
void op_four ()
{
stct tmp = tot;ll sum = 0,k,ok;cin>>k;
while (1)
{
ok = 0;
for (ele x : tmp.v)
{
calc (sum,x.ali_len);
if (sum <= k && k < sum + x.len)//在某个变量的区间中
{
if (bs[x.ty]) {ok = 1;break;}//是最小单元,说明存在解
tmp = ext[x.ty];//向内层走
ok = 2;break;
}
sum += x.len;
if (sum > k) {ok = 0;break;}
}
if (!ok || ok == 1) break;
}
if (!ok) {puts ("ERR");return ;}
sum = 0;tmp = tot;
while (1)
{
for (ele x : tmp.v)
{
calc (sum,x.ali_len);
if (sum <= k && k < sum + x.len)
{
cout<<x.name;
if (bs[x.ty]) {puts ("");return ;}
tmp = ext[x.ty];cout<<".";
break;
}
sum += x.len;
}
}
}
T4 \texttt{T4} T4 其实但凡做了这题目多少也可得点分。(后悔.jpg)。树上的二分套二分,显然二分天数以及至少要中的时间,唯一的坑点就是可能爆 long long \texttt{long long} long long。
得分: 100 + 35 + 0 + 0 = 135 100 + 35 + 0 + 0 = 135 100+35+0+0=135。为什么要写大模拟!!!为什么不做 T4 \texttt{T4} T4!!!【所以依旧获得 2 = 2= 2=】
2023.11.8 2023.11.8 2023.11.8
市一模考完,润到机房!(奈斯的安排,第三天上午就考完!【笑死我,有的人,在别人全考完的时候还没开始考……】)
【 PS \texttt{PS} PS:喜提年排 28 28 28, OI \texttt{OI} OI 助我一臂之力。】
下午做洛谷模拟赛。
T1 \texttt{T1} T1 数论题,翻译一下就是给长度为 n n n 的序列 a a a 和一个数 w w w,每次操作你可以选择一个 a i a_i ai 使得 a i = a i + 1 a_i = a_i + 1 ai=ai+1,至多操作 w w w 次,最大化 Π i = 1 w a i \Pi_{i = 1}^{w} a_i Πi=1wai。做法就是贪心选择最小值, O ( n 2 ) O(n^2) O(n2) 即可。
T2 \texttt{T2} T2 找规律(赛时没找到,寄),在直到规律后,代码短的离谱。
T3,T4 \texttt{T3,T4} T3,T4 好像没做。
2023.11.12 − 14 2023.11.12-14 2023.11.12−14
翘了运动会,打三套模拟赛,做 NOIP \texttt{NOIP} NOIP 最后的冲刺。反正打得不错,具体就不写了。
2023.11.18 2023.11.18 2023.11.18
比赛日。
8:30 \texttt{8:30} 8:30 开始比赛,用福昕阅读器解码 pdf \texttt{pdf} pdf 多次失败,后来说要从浏览器这里打开才行……
8:35 \texttt{8:35} 8:35 写完缺省,开始读题。似乎是模拟 + + + 图论 + + + 盲猜数据结构 + + + 盲猜数据结构/动态规划,猜的还挺准的。
8:45 \texttt{8:45} 8:45 开始写 T1 \texttt{T1} T1,真的是三年来最简单的签到题,记录一下最大最小值,然后直接 O ( n 2 ) O(n^2) O(n2) 判断即可。
9:00 \texttt{9:00} 9:00 写完,开始看 T2 \texttt{T2} T2,发现有 40 pts \texttt{40 pts} 40 pts 是送的,直接敲。然后开始想正解,其间一直没用想通一个能成环的样例,所以一直手模构造,好像花了很久,然后尝试写了代码,但是一直出不来。代码越改越乱,大样例全过不了,稍微有点慌。这时候大概已经 10:20 \texttt{10:20} 10:20 的样子了,吸取了之前的教训,出去上了个厕所,直接开写 T3 \texttt{T3} T3。
想到一个 35 pts \texttt{35 pts} 35 pts 的朴素 dp \texttt{dp} dp,设 d p i , j dp_{i,j} dpi,j 表示 X X X 匹配到第 i i i 位, Y Y Y 匹配到第 j j j 位是否可行,所以就有转移 d p i , j = d p i − 1 , j ∣ d p i , j − 1 ∣ d p i − 1 , j − 1 dp_{i,j} = dp_{i - 1,j} | dp_{i,j - 1} | dp_{i - 1,j - 1} dpi,j=dpi−1,j∣dpi,j−1∣dpi−1,j−1。整一个想完写完大概 11:40 \texttt{11:40} 11:40,拍了大样例,能过,一阵狂喜,然后开最后一题。
按照赛前“没思路就写
dp
\texttt{dp}
dp”的策略,很快想出一个
36
pts
\texttt{36 pts}
36 pts 的
dp
\texttt{dp}
dp,
d
p
i
,
j
dp_{i,j}
dpi,j 表示到第
i
i
i 天时,
(
j
,
i
)
(j,i)
(j,i) 区间均打卡而第
j
−
1
j - 1
j−1 天不打卡的最大能量。差不多
12:30
\texttt{12:30}
12:30,测大样例,突然发现有问题。一顿检查后发现是初始化的锅,修了以后所以大样例都能过。写完以后怕被卡常,在判断
(
j
,
i
)
(j,i)
(j,i) 区间的代码中利用 vector
加了一个二分,改完以后继续按原程序对拍,还真个我拍出错来了,发现还是初始化的问题,赶紧改!
12:45
\texttt{12:45}
12:45,不写了,开始检查文件名,路径,freopen
等等。
13:00 \texttt{13:00} 13:00,比赛结束,感觉还行,估分 100 + 40 + 25 + 36 = 211 100 + 40 + 25 + 36 = 211 100+40+25+36=211。
后记
-
这场比赛还是有一点点不满意。 T2 \texttt{T2} T2 应该是要写出来的,考场上想得太乱把自己绕进去了。 T4 \texttt{T4} T4 还有离散化的那一部分分没看见,这是可以拿到的;好像还有 10 pts \texttt{10 pts} 10 pts 的特殊部分也没看见……
-
感谢 CCF \texttt{CCF} CCF 没有卡 T3 \texttt{T3} T3 的大常数做法(虽然能够通过读入时的特判解决这个问题)。以及 T2 \texttt{T2} T2 暴力不小心把 n n n 打成了 m m m,但由于暴力肯定是卡满的,所以出的数据全部都 n = m n = m n=m(属于是逃过一劫了)。
-
出分啦,和自己估的一毛一样。感觉有点悬,祈祷初中生能去除的多一点。
-
出分数线啦! 206 206 206!终于终于终于一等奖嘞!!!上体育课前同学来告诉我的,让我给激动得不得了。
-
初高中的 OI \texttt{OI} OI 总算有了闭环,或许整个过程看上去很艰难,经历了停文化课,比赛失利等困难,但是我真的乐在其中。不论是洛谷的月赛,还是 CF \texttt{CF} CF 的深夜鏖战,总之努力没有白费!!!
-
高中的竞赛算是结束了,但是洛谷的账号我是不会废滴,希望我在大学是能参加 ACM \texttt{ACM} ACM,然后继续开始写我的题解,赚我的咕值,提升我的排名!!!
-
最后最后,纪念一下我比赛的四道题的赛时代码。
//T1
#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int MAX = 3e3 + 5;
const int MOD = 1e9 + 7;
inline int read ();
int n,m,mx[MAX],mn[MAX];char s[MAX][MAX];
int main ()
{
n = read ();m = read ();
for (int i = 1;i <= n;++i) mn[i] = INF;
for (int i = 1;i <= n;++i) scanf ("%s",s[i] + 1);
for (int i = 1;i <= n;++i)
for (int j = 1;j <= m;++j)
mx[i] = max (mx[i],s[i][j] - 'a'),mn[i] = min (mn[i],s[i][j] - 'a');
for (int i = 1;i <= n;++i)
{
int ok = 1;
for (int j = 1;j <= n;++j)
{
if (i == j) continue;
if (mn[i] >= mx[j]) {ok = 0;break;}
}
if (ok) printf ("1");
else printf ("0");
}
puts ("");
return 0;
}
inline int read ()
{
int s = 0,f = 1;
char ch = getchar ();
while (('0' > ch || ch > '9') && ch != EOF)
{
if (ch == '-') f = -1;
ch = getchar ();
}
while ('0' <= ch && ch <= '9')
{
s = s * 10 + ch - '0';
ch = getchar ();
}
return s * f;
}
//T2
#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int MAX = 1e5 + 5;
const int MOD = 1e9 + 7;
inline int read ();
int ty,t,n,m,cnt,ans,vis[MAX],a[MAX],b[MAX],st[MAX];
//st[i] for i,the priority
char str[30][2];int x[30],y[30];
vector <pair <int,int> > ve[MAX];
void dfs (int u,int ti);
void solve (int x);
bool check ();
int main ()
{
// freopen ("tribool.in","r",stdin);
// freopen ("tribool.out","w",stdout);
ty = read ();t = read ();
if (ty <= 2)
{
while (t--)
{
n = read ();m = read ();ans = INF;
for (int i = 1;i <= m;++i)
{
scanf ("%s",str[i]);x[i] = read ();
if (str[i][0] == '+' || str[i][0] == '-') y[i] = read ();
}
solve (1);
printf ("%d\n",ans);
}
return 0;
}
while (t--)
{
n = read ();m = read ();cnt = 0;
for (int i = 1;i <= n;++i) a[i] = 0,st[i] = 0,ve[i].clear ();
for (int i = 1;i <= m;++i)
{
char s[2];scanf ("%s",s);
if (s[0] == '+')
{
int x = read (),y = read ();
ve[y].push_back ({x,i});
st[x] = i;
for (int j = 1;j <= n;++j) vis[j] = 0;
dfs (y,i);
}
else if (s[0] == '-')
{
int x = read (),y = read ();
}
else
{
int x = read ();
if (s[0] == 'T') a[x] = 1;
if (s[0] == 'F') a[x] = 2;
if (s[0] == 'U') a[x] = 3;
if (ty >= 5)
{
st[x] = i;
for (int j = 1;j <= n;++j) vis[j] = 0;
dfs (x,i);
}
}
}
for (int i = 1;i <= n;++i)
if (a[i] == 3) ++cnt;
printf ("%d\n",cnt);
}
return 0;
}
inline int read ()
{
int s = 0,f = 1;
char ch = getchar ();
while (('0' > ch || ch > '9') && ch != EOF)
{
if (ch == '-') f = -1;
ch = getchar ();
}
while ('0' <= ch && ch <= '9')
{
s = s * 10 + ch - '0';
ch = getchar ();
}
return s * f;
}
void dfs (int u,int ti)
{
vis[u] = 1;
for (int i = 0;i < ve[u].size ();++i)
{
int v = ve[u][i].first;
if (vis[v] || st[v] != ve[u][i].second) continue;
a[v] = a[u];//st[v] = ti;
dfs (v,ti);
}
}
void solve (int x)
{
if (x == n + 1)
{
if (check ())
{
int sum = 0;
for (int i = 1;i <= n;++i) sum += (a[i] == 3);
ans = min (ans,sum);
}
return ;
}
for (int i = 1;i <= 3;++i) a[x] = i,solve (x + 1);
}
bool check ()
{
for (int i = 1;i <= n;++i) b[i] = a[i];
for (int i = 1;i <= m;++i)
{
if (str[i][0] == '+') b[x[i]] = b[y[i]];
else if (str[i][0] == '-')
{
if (b[y[i]] == 3) b[x[i]] = b[y[i]];
else b[x[i]] = 3 - b[y[i]];
}
else
{
if (str[i][0] == 'F') b[x[i]] = 1;
if (str[i][0] == 'T') b[x[i]] = 2;
if (str[i][0] == 'U') b[x[i]] = 3;
}
}
for (int i = 1;i <= n;++i)
if (a[i] != b[i]) return 0;
return 1;
}
//T3
#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int MAX = 2e3 + 5;
const int MOD = 1e9 + 7;
inline int read ();
int ty,n,m,q,ans,a[MAX],b[MAX],c[MAX],d[MAX],dp[MAX][MAX];
bool check1 ();
bool check2 ();
int main ()
{
// freopen ("expand.in","r",stdin);
// freopen ("expand.out","w",stdout);
ty = read ();n = read ();m = read ();q = read ();
for (int i = 1;i <= n;++i) a[i] = read ();
for (int i = 1;i <= m;++i) b[i] = read ();
if (a[1] > b[1]) ans = check1 ();
else ans = check2 ();
printf ("%d",ans);
while (q--)
{
int dx = read (),dy = read ();
for (int i = 1;i <= n;++i) c[i] = a[i];
for (int i = 1;i <= m;++i) d[i] = b[i];
while (dx--)
{
int x = read (),y = read ();
a[x] = y;
}
while (dy--)
{
int x = read (),y = read ();
b[x] = y;
}
if (a[1] > b[1]) ans = check1 ();
else ans = check2 ();
printf ("%d",ans);
for (int i = 1;i <= n;++i) a[i] = c[i];
for (int i = 1;i <= m;++i) b[i] = d[i];
}
puts ("");
return 0;
}
inline int read ()
{
int s = 0,f = 1;
char ch = getchar ();
while (('0' > ch || ch > '9') && ch != EOF)
{
if (ch == '-') f = -1;
ch = getchar ();
}
while ('0' <= ch && ch <= '9')
{
s = s * 10 + ch - '0';
ch = getchar ();
}
return s * f;
}
bool check1 ()
{
for (int i = 1;i <= n;++i)
for (int j = 1;j <= m;++j) dp[i][j] = 0;
dp[1][1] = (a[1] > b[1]);
for (int i = 1;i <= n;++i)
{
for (int j = 1;j <= m;++j)
{
if (i == 1 && j == 1) continue;
if (a[i] <= b[j]) continue;
dp[i][j] |= dp[i][j - 1];
dp[i][j] |= dp[i - 1][j - 1];
dp[i][j] |= dp[i - 1][j];
}
}
return dp[n][m];
}
bool check2 ()
{
for (int i = 1;i <= n;++i)
for (int j = 1;j <= m;++j) dp[i][j] = 0;
dp[1][1] = (a[1] < b[1]);
for (int i = 1;i <= n;++i)
{
for (int j = 1;j <= m;++j)
{
if (i == 1 && j == 1) continue;
if (a[i] >= b[j]) continue;
dp[i][j] |= dp[i][j - 1];
dp[i][j] |= dp[i - 1][j - 1];
dp[i][j] |= dp[i - 1][j];
}
}
return dp[n][m];
}
//T4
#include <bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
const int MAX = 1e3 + 5;
const int MOD = 1e9 + 7;
inline int read ();
struct node
{
int ti;ll v;
} ;
int ty,t,n,m,k,d;
ll ans,dp[MAX][MAX];
vector <node> p[MAX];
vector <ll> sum[MAX];
bool cmp (node x,node y);
ll check (int x,int y);
int main ()
{
// freopen ("run.in","r",stdin);
// freopen ("run.out","w",stdout);
ty = read ();t = read ();
while (t--)
{
n = read ();m = read ();k = read ();d = read ();
for (int i = 1;i <= n;++i)
for (int j = 0;j <= min (n,k);++j) dp[i][j] = -INF;
ans = -INF;
for (int i = 1;i <= m;++i)
{
int x = read (),y = read (),v = read ();
p[x].push_back ({x - y + 1,v});
}
for (int i = 1;i <= n;++i) sort (p[i].begin (),p[i].end (),cmp);
for (int i = 1;i <= n;++i)
{
if (!p[i].size ()) continue;
sum[i].push_back (p[i][0].v);
for (int j = 1;j < p[i].size ();++j) sum[i].push_back (sum[i][j - 1] + p[i][j].v);
}
dp[0][0] = 0;
for (int i = 1;i <= n;++i)
{
for (int j = 0;j <= min (i,k);++j)
{
int l = max (i - j + 1,1),r = i;
dp[i][0] = max (dp[i][0],dp[i - 1][j]);
if (j) dp[i][j] = max (dp[i][j],dp[i - 1][j - 1] + check (l,r) - d);
}
}
for (int i = 0;i <= min (n,k);++i) ans = max (ans,dp[n][i]);
printf ("%lld\n",ans);
for (int i = 1;i <= n;++i) p[i].clear (),sum[i].clear ();
for (int i = 1;i <= n;++i)
for (int j = 0;j <= min (n,k);++j) dp[i][j] = -INF;
}
return 0;
}
inline int read ()
{
int s = 0,f = 1;
char ch = getchar ();
while (('0' > ch || ch > '9') && ch != EOF)
{
if (ch == '-') f = -1;
ch = getchar ();
}
while ('0' <= ch && ch <= '9')
{
s = s * 10 + ch - '0';
ch = getchar ();
}
return s * f;
}
bool cmp (node x,node y)
{
return x.ti < y.ti;
}
ll check (int x,int y)
{
int l = 0,r = p[y].size () - 1,ans = -1;
while (l <= r)
{
int mid = (l + r) >> 1;
if (x <= p[y][mid].ti) ans = mid,r = mid - 1;
else l = mid + 1;
}
if (ans == -1) return 0;
if (ans == 0) return sum[y][sum[y].size () - 1];
else return sum[y][sum[y].size () - 1] - sum[y][ans - 1];
}