zoukankan      html  css  js  c++  java
  • CF1580C(根号分治)

    一道根号分治题

    题目描述

    (n) 台设备,将第 (i) 台投入使用有 (x_i) 的运行时间和 (y_i) 的维护时间,两种状态交替。现在有 (m) 的时间,每单位时间会发生两种事件之一:

    • 将某台设备投入使用
    • 将某台设备报废,注意之后可以重新加入。

    求每单位时间在维护的设备数。

    考虑设置一个阈值 (S = sqrt(m))

    若加入的一个列车 (x_i + y_i leq S) 则:

    维护一个 (dp[a][b]) 意义是 ( m 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
    ",ans);
    }
    
    signed main()
    {
        int n,m;
        read(n),read(m);
        T = sqrt(m);
    //    T = 1;
    //    T = 100;
    //    printf("%d
    ",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;
    }
    
  • 相关阅读:
    git使用记录
    【转】话说我打算一天学完object c语法,系列1--------来自书Objective-c程序设计
    【转】看源代码那些事
    中英文对照 —— 数学定律定理(公式及其描述)
    CUDA+OpenGL混合编程
    简明欧洲史
    简明欧洲史
    CUDA一维纹理内存
    CUDA中的常量内存__constant__
    CUDA线程协作之共享存储器“__shared__”&&“__syncthreads()”
  • 原文地址:https://www.cnblogs.com/-Iris-/p/15377026.html
Copyright © 2011-2022 走看看