CF1580C(根号分治)
Posted ·Iris
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1580C(根号分治)相关的知识,希望对你有一定的参考价值。
一道根号分治题
题目描述
有 \\(n\\) 台设备,将第 \\(i\\) 台投入使用有 \\(x_i\\) 的运行时间和 \\(y_i\\) 的维护时间,两种状态交替。现在有 \\(m\\) 的时间,每单位时间会发生两种事件之一:
- 将某台设备投入使用
- 将某台设备报废,注意之后可以重新加入。
求每单位时间在维护的设备数。
考虑设置一个阈值 \\(S = \\sqrt(m)\\)
若加入的一个列车 \\(x_i + y_i \\leq S\\) 则:
维护一个 \\(dp[a][b]\\) 意义是 \\(\\rm mod a\\) 的情况下余 \\(b\\)。
然后前缀和一下就行。
当大于这个阈值的时候,直接在长为 \\(m\\) 的序列上进行覆盖即可(撤销的时候特殊处理一下
#include<bits/stdc++.h>
using namespace std;
// #define INF 1<<30
// #define int long long
#define pb emplace_back
template<typename _T>
inline void read(_T &x)
{
x= 0 ;int f =1;char s=getchar();
while(s<\'0\' ||s>\'9\') {f =1;if(s == \'-\')f =- 1;s=getchar();}
while(\'0\'<=s&&s<=\'9\'){x = (x<<3) + (x<<1) + s - \'0\';s= getchar();}
x*=f;
}
const int np = 2e5 + 5;
const int cp = sqrt(np) + 50;
int dp[cp][cp];
// vector<int> dp[2333];
int x[np],y[np],T;
int b[np],la[np];
int qb[np];
// vector<>
inline void solve(int x)
{
// b[x] += b[x - 1];
qb[x] = qb[x - 1] + b[x];
int ans = qb[x];
for(int i=2;i <= T;i ++)
{
int op = x % i;
ans += dp[i][op];
}
printf("%d\\n",ans);
}
signed main()
{
int n,m;
read(n),read(m);
T = sqrt(m);
// T = 1;
// T = 100;
// printf("%d\\n",T);
for(int i=1;i <= n;i ++)
{
read(x[i]),read(y[i]);
}
for(int i=1,k,op;i <= m;i ++)
{
read(op),read(k);
if(op == 1)
{
la[k] = i;
if(x[k] + y[k] <= T)
{
for(int u = 1 ;u <= y[k] ;u ++)
{
// i%(x[k]+y[k])
dp[x[k] + y[k]][((i + x[k]-1) % (x[k] + y[k]) + u) % (x[k] + y[k])] += 1;
}
// dp[x[k] + y[k]][]
// dp[x[k] + y[k]].pb(i % (x[k] + y[k]) + x[k]);
}
else{
for(int u=i ;u<= m;u += x[k] + y[k])
{
if(u + x[k] <= m) b[u + x[k]] += 1;
if(u + x[k] + y[k] <= m) b[u + x[k] + y[k]] -= 1;
}
}
}
else{
if(x[k] + y[k] <= T)
{
for(int u = 1 ;u <= y[k] ;u ++)
{
dp[x[k] + y[k]][((la[k]+x[k]-1) % (x[k] + y[k]) + u) % (x[k] + y[k])] -= 1;
}
}
else{
int opt = 0;
for(int u=la[k] ;u<= m;u += x[k] + y[k])
{
if(u + x[k] <= m) b[u + x[k]] -= 1;
if(u + x[k] <= i-1) opt -= 1;
if(u + x[k] + y[k] <= m) b[u + x[k] + y[k]] += 1;
if(u + x[k] + y[k] <= i-1) opt += 1;
}
qb[i-1] += opt;
}
}
solve(i);
}
return 0;
}
以上是关于CF1580C(根号分治)的主要内容,如果未能解决你的问题,请参考以下文章
CF E. Till I Collapse 整体二分+根号分治