abc233
这场比赛编号是 233,好玩好玩
D - Count Interval
给出 \(n\) 个数,求有多少个连续段的和为 \(K\).
即求出 \((l,r)\) 的个数,\((l,r)\) 满足
\(1. 1\leq l\leq r\leq n\)
\(2. \sum\limits_{i=l}^{r} a_i=K\)
\(1\leq n\leq 2\cdot 10^5,\ |a_i|\leq 10^9,\ |K|\leq 10^{15}\)
考虑 \(\sum\limits_{i=l}^{r} a_i=\sum\limits_{i=1}^{r} a_i-\sum\limits_{i=1}^{l-1} a_i\) .
考虑用 \(\mathrm{map}\) 维护前缀和的数的数量即可.
时间复杂度 : \(O(n\log n)\)
空间复杂度 : \(O(n)\)
code
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n;
long long k;
long long a[N];
map<long long,int>cnt;
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n>>k;
for(int i=0;i<n;i++)cin>>a[i];
for(int i=1;i<n;i++)a[i]+=a[i-1];
long long ans=0;
cnt[0]++;
for(int i=0;i<n;i++){
ans+=cnt[a[i]-k];
cnt[a[i]]++;
}
cout<<ans<<endl;
return 0;
}
E - Σ[k=0..10100]floor(X/10k)
求 \(\sum\limits_{k=0}^{10^{100}}\lfloor \frac{X}{10^k}\rfloor\) .
\(1\leq X\leq 10^{500000}\)
这个式子相当于每次把这个数的最后一位删掉,得到 \(|X|\) 个数,然后把这些数相加.
这样肯定会 ttt,考虑答案中的第 \(i\) 位是原数位数中不大于 \(i\) 的所有加起来.
不能忘记考虑进位.
时间复杂度 : \(O(n)\)
空间复杂度 : \(O(n)\)
code
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n;
long long k;
long long a[N];
map<long long,int>cnt;
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n>>k;
for(int i=0;i<n;i++)cin>>a[i];
for(int i=1;i<n;i++)a[i]+=a[i-1];
long long ans=0;
cnt[0]++;
for(int i=0;i<n;i++){
ans+=cnt[a[i]-k];
cnt[a[i]]++;
}
cout<<ans<<endl;
return 0;
}
F - Swap and Sort
给出一个长度为 \(n\) 的排列 \(P\) .
给出 \(m\) 种操作. 第 \(i\) 种操作交换 \(P\) 中的第 \(a_i\) 个和第 \(b_i\) 个.
求是否能在不多于 \(5\cdot 10^5\) 次操作后排列有序.
如果能,给出方案.
\(1\leq n\leq 1000,1\leq m\leq \min(5\cdot 10^5,\frac{n(n-1}{2})\)
考虑 \(a_i\) 和 \(b_i\) 连边构图.
如果存在 \(i\) 和 \(P_i\) 不连通,那么肯定没有解.
对于一个连通块,保留一棵生成树就可以做到所有点都回到原本的位置上.
但是对于生成树的点操作的顺序是有讲究的. 考虑剥叶子,让位于叶子节点处的节点先通过操作回到原本的位置,然后再删掉这个节点.
操作方案即为 \(i\) 到 \(P_i\) 上的边依次 swap.
时间复杂度 : \(O(n^2)\)
空间复杂度 : \(O(n+m)\)
code
```cpp #include</details>
#### G - Strongest Takahashi
> 给出一个 $n\times n$ 的格子. 每个格子为 `.` 或 `#` .
>
> 每次可以选出其中一个 $d\times d$, 花费 $d$ 的代价将其全部覆盖为 `.`
>
> 问将全部格子覆盖成 `.` 的代价.
>
> $1\leq n\leq 50$
考虑 $dp(x_1,y_1,x_2,y_2)$ 表示左上角为 $(x_1,y_1)$ 右下角为 $(x_2,y_2)$ 的矩形覆盖为 `.` 的最小代价.
转移的时间枚举横着切和纵着切的位置,合并取 $\min$ 即可.
时间复杂度 : $O(n^5)$
空间复杂度 : $O(n^4)$
<details>
<summary>code</summary>
```c++
#include<bits/stdc++.h>
using namespace std;
const int N=52;
const int INF=0x3f3f3f3f;
const int inf=1061109567;
int n;
char board[N][N];
bool ok[N][N][N][N];
int dp[N][N][N][N];
int dfs(int x1,int y1,int x2,int y2){
if(dp[x1][y1][x2][y2]!=inf)return dp[x1][y1][x2][y2];
if(x1==x2&&y1==y2)return dp[x1][y1][x2][y2]=ok[x1][y1][x2][y2]?0:1;
int&res=dp[x1][y1][x2][y2];
for(int x3=x1;x3<x2;x3++){
res=min(res,dfs(x1,y1,x3,y2)+dfs(x3+1,y1,x2,y2));
}
for(int y3=y1;y3<y2;y3++)res=min(res,dfs(x1,y1,x2,y3)+dfs(x1,y3+1,x2,y2));
if(ok[x1][y1][x2][y2])res=min(res,0);
res=min(res,max(x2-x1+1,y2-y1+1));
return res;
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n;
for(int i=0;i<n;i++)for(int j=0;j<n;j++)cin>>board[i][j];
for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(board[i][j]=='.')ok[i][j][i][j]=true;
for(int L1=1;L1<=n;L1++)for(int L2=1;L2<=n;L2++){
for(int x1=0;x1<n;x1++)if(x1+L1-1<n){
for(int y1=0;y1<n;y1++)if(y1+L2-1<n){
int x2=x1+L1-1,y2=y1+L2-1;
if(L2!=1)ok[x1][y1][x2][y2]=ok[x1][y1][x2][y2-1]&ok[x1][y2][x2][y2];
else if(L1!=1)ok[x1][y1][x2][y2]=ok[x1][y1][x2-1][y2]&ok[x2][y1][x2][y2];
}
}
}
memset(dp,INF,sizeof(dp));
cout<<dfs(0,0,n-1,n-1)<<endl;
return 0;
}
/*inline? ll or int? size? min max?*/
21
.....................
.....................
...#.#...............
....#.............#..
...#.#...........#.#.
..................#..
.....................
.....................
.....................
..........#.....#....
......#..###.........
........#####..#.....
.......#######.......
.....#..#####........
.......#######.......
......#########......
.......#######..#....
......#########......
..#..###########.....
.........###.........
.........###.........
haha, Merry Christmas and Happy New Year !
Ex - Manhattan Christmas Tree
给出 \(n\) 棵圣诞树的位置. 给出 \(q\) 个询问.
每个询问问距离 \((x,y)\) 位置曼哈顿距离最近的第 \(k\) 个点.
\(1\leq n\leq 10^5,\ 1\leq q\leq 10^5,\ 0\leq x,y\leq 10^5,\) 圣诞树的坐标不相同.
考虑二分距离 \(d\) , 如果是曼哈顿距离,那么构成的图形是一个斜着的矩形,求这个范围内的点是不好求的.
此时,有一个 trick,就是把切比雪夫转化,相当于逆时针旋转 \(45\) 度之后坐标乘上 \(\sqrt 2\). 在曼哈顿距离下为 \((x,y)\) 的坐标会变成 \((x-y,x+y)\). 但是此时距离当前询问的点小于等于距离为 \(d\) 的位置是一个正方形. 这就非常惹人喜爱.
看到 \(x,y\) 在 \(0\) 到 \(10^5\) 之内,所以切比雪夫之后,\(x,y\) 在 \(-10^5\) 到 \(2\cdot 10^5\) 之内.
考虑建立主席树,线段树上维护横坐标,每次加入一行,多次单点修改,维护新的根节点.
查询的时候只需要区间询问两次做一个差即可.
时间复杂度 : \(O(n\log^2 x)\)
空间复杂度 : \(o(n\log n)\)

浙公网安备 33010602011771号