RT,训练赛复盘+题解,赛中过8题,比理论上界少1题(
总体来说发挥平稳。
开始复盘吧。 (按照时间顺序来的)
B是啥东西不知道,卢姥爷一发就过去了。
J听ghj说是个开关灯问题,线性基,01矩阵求逆,高斯消元,他也是一发就过去了。
E是个简单DP,问题转化一下,变成两条长链,无向边,给边定向,求对应点入度差能否为d数组。
考虑状态为dp[loc][val1][val2],即,处理完前loc条边,对于第loc+1对点,上面那个点入度val1,下面那个点入度val2,考虑合法转移,一定是使得第loc+1对点满足d数组的,然后一发就过去了。
H题听ghj说是个FFT裸题,上面两个数组卷起来下标除二,对着中间数组判一判。他也是一发就过去了。
C题:读题不规范,本来卢姥爷搞到了正解,我听他复述了一波题意之后发现是个对于每个关键点找最近点HHHHHH,然后不出所料Wa3。
改正之后就是个虚树上面的所有点,随便搞搞就行了。没有采用dfs序建虚树,每次抓一个最深的点,大力跳father就好了,证一证可以发现复杂度是对的。
G题:一波猛卡,然后我读题假了,没发现那个标号的限制,这波是我的锅,而且我还口胡了个三分HHHH这波是死透
考虑如果没有标号限制,那么固定了最左端的点的位置之后,就变成了取个min的事儿。
考虑每个点需要走的路程与最左端那个点的位置的关系。一定是一堆‘V’形的并,则一头一尾取一下就好。
由于要固定顺序,那么顺序有两种,正序和反序,然后枚举1号点在左在右就行了。
注意此题有坑,如果你用double除二,那么在LL范围内,是有东西可以让你在第一位小数出精度误差的。这个很要命,所以特判掉那个除二。
I题:
注意到子串一共只有2e6个,询问2e5。
考虑那个奇妙的限制,比U小的列入考虑范围,比U大的的不予考虑。
有没有点时间轴的味道?如果觉得有,那就对了。
大力出所有子串的子串和,离线下来所有询问,把询问的U与子串的和作为时间轴,转化为:支持插入,二维前缀max的问题。
摸出二维BIT,切之。(YYSY我头一次知道BIT还能二维)
A题:
题目保证,交点一定是十字路口,那就好办不少了。
我们考虑人在线里走。那么,首先处理所有的交点,然后把他们和端点一块儿,扔进node里面,记录下每个点是交点还是端点。
对node集合一顿操作,处理出每个点的上下左右第一个点分别是什么。
人记录当前点和行进方向,如果当期点是一个四联通点,那么走了之后要左转,如果是个路径端点,那么要回头。
挺长,但是不难写。
写完之后改了个CE就过了,这波是状态在线。
贴个代码吧,这东西口胡起来挺抽象的。
#include<bits/stdc++.h>
using namespace std;
int n,T;
int x1[510],y1[510],x2[510],y2[510];
int pcnt;
//0 = U; 1 = L; 2 = D; 3 = R;
int neig[300010][4];//ori中,第loc号点在dir方向上的邻居
struct node {
int x,y,pos,type;
};
node ori[300010], sth[300010];
int gdist(int a,int b) {
return abs(ori[a].x - ori[b].x) + abs(ori[a].y - ori[b].y);
}
bool cmp1(node &a,node &b) {
if(a.x == b.x)
return a.y < b.y;
else
return a.x < b.x;
}
bool cmp2(node &a,node &b) {
if(a.y == b.y)
return a.x < b.x;
else
return a.y < b.y;
}
int main() {
scanf("%d%d",&n,&T);
for(int i=1;i<=n;++i) {
scanf("%d%d%d%d",&x1[i],&y1[i],&x2[i],&y2[i]);
ori[++pcnt] = {x1[i], y1[i], pcnt, 1};
ori[++pcnt] = {x2[i], y2[i], pcnt, 1};
}
for(int i=1;i<=n;++i) {
if(x1[i] != x2[i])
continue;
for(int j=1;j<=n;++j) {
if(y1[j] != y2[j])
continue;
int ymi = min(y1[i], y2[i]);
int yma = max(y1[i], y2[i]);
int xmi = min(x1[j], x2[j]);
int xma = max(x1[j], x2[j]);
if(ymi < y1[j] && yma > y1[j] && xmi < x1[i] && xma > x1[i]) {
ori[++pcnt] = {x1[i],y1[j],pcnt, 4};
}
}
}
for(int i=1;i<=pcnt;++i)
sth[i] = ori[i];
//搞出邻居
sort(sth+1,sth+pcnt+1,cmp1);
for(int i=1;i<pcnt;++i)
if(sth[i].x == sth[i+1].x)
neig[sth[i].pos][0] = sth[i+1].pos;
for(int i=2;i<=pcnt;++i)
if(sth[i].x == sth[i-1].x)
neig[sth[i].pos][2] = sth[i-1].pos;
sort(sth+1,sth+pcnt+1,cmp2);
for(int i=1;i<pcnt;++i)
if(sth[i].y == sth[i+1].y)
neig[sth[i].pos][3] = sth[i+1].pos;
for(int i=2;i<pcnt;++i)
if(sth[i].y == sth[i-1].y)
neig[sth[i].pos][1] = sth[i-1].pos;
for(int i=1;i<=pcnt;++i) {
// printf("%d : %d %d %d %d %d %d\n",i,ori[i].x,ori[i].y,neig[i][0],neig[i][1],neig[i][2],neig[i][3]);
}
//起点定向
long long totlen = 0;
int nloc = 1,ndir = 0;
int mark = 0;
if(x1[1] == x2[1]) {
if(y1[1] > y2[1])
ndir = 0;
else
ndir = 2;
}
else {
if(x1[1] > x2[1])
ndir = 3;
else
ndir = 1;
}
//算出一圈多长
while(1) { //only contact not turn
if(nloc == 1) {
if(mark)
break;
else
mark = 1;
}
if(ori[nloc].type == 1) {
ndir = (ndir + 2) % 4;
}
else if(ori[nloc].type == 4) {
ndir = (ndir + 1) % 4;
}
int tar = neig[nloc][ndir];
int deltalen = gdist(nloc, tar);
totlen += deltalen, nloc = tar;
}
T %= totlen;
//redirection
if(x1[1] == x2[1]) {
if(y1[1] > y2[1])
ndir = 0;
else
ndir = 2;
}
else {
if(x1[1] > x2[1])
ndir = 3;
else
ndir = 1;
}
while(1) { //only contact not turn
if(ori[nloc].type == 1) {
ndir = (ndir + 2) % 4;
}
else if(ori[nloc].type == 4) {
ndir = (ndir + 1) % 4;
}
int tar = neig[nloc][ndir];
int deltalen = gdist(nloc, tar);
if(T >= deltalen) {
T -= deltalen;
nloc = tar;
}
else {
if(ori[nloc].x == ori[tar].x) {
if(ori[tar].y > ori[nloc].y) {
printf("%d %d\n",ori[nloc].x, ori[nloc].y + T);
return 0;
}
else {
printf("%d %d\n",ori[nloc].x, ori[nloc].y - T);
return 0;
}
}
else {
if(ori[tar].x > ori[nloc].x) {
printf("%d %d\n",ori[nloc].x + T, ori[nloc].y);
return 0;
}
else {
printf("%d %d\n",ori[nloc].x - T, ori[nloc].y);
return 0;
}
}
}
}
return 0;
}
总结一下吧,这次训练赛的时间有点阴间,1430-1930,中途我和ghj都出现了犯困降频的情况HHHHH。大家的状态都很不错,无论是代码稳定性还是思维速度,都发挥出了队伍应有的水准,且没有出现三人卡三题的要命情况,赛时沟通到位。赛后的萨莉亚真好吃HHHHH
体现出来的问题:
连续两场比赛的DP优化题,我们都知道这个是DP优化,但是都不会做。这波是漏知识点。本场的L题与上一场的WQS二分,都是DP优化里面的内容,感觉这波得补,不然吃枣药丸。
读题读题读题读题读题读题