首页 > 其他分享 >题解 SP10264 METEORS - Meteors

题解 SP10264 METEORS - Meteors

时间:2022-12-17 12:22:17浏览次数:40  
标签:Meteors int 题解 个数 差分 sqrt 操作 METEORS ql

整体二分经典题,所以我们用分块解决

Solution

和整体二分类似,我们把 \(k\) 次操作分成 \(\sqrt k\) 块,每一块一起考虑。对于区间加,可以转化为差分,那么在每个块一起作差分后再作前缀和即可得到当前操作块后每段路的陨石个数,然后加进其所属国家的总个数。接着看一遍所有国家,如果在这整块操作后陨石个数已满足要求,就说明满足的时间就在这块之内,直接暴力倒着扫一遍这块操作,找到具体满足的时间即可。

怎么倒着扫一遍操作呢,之前不是用差分来转化的吗?由于只考虑当前国家,每个操作只用逐个判断这个国家的每段路是否在操作区间内,如果在就给国家总个数减去,减到小于需求就说明当前操作的时间即为答案。

统计 \(\sqrt k\) 次差分前缀和,且每个国家只会暴力倒着扫一次,复杂度为 \(\mathcal O((m+n)\sqrt k)\)。

Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=3e5+5;
int n,m,q,blo,tot,bel[N],ans[N],p[N],ql[N],qr[N],qw[N];
ll sum[N],d[N],a[N];
vector<int>v[N];
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1,x;i<=m;i++){
        scanf("%d",&x);
        v[x].push_back(i);
        bel[i]=x;
    }for(int i=1;i<=n;i++)scanf("%d",p+i);
    scanf("%d",&q);blo=sqrt(q);tot=q/blo+(q%blo!=0);
    for(int i=1;i<=q;i++)scanf("%d%d%d",ql+i,qr+i,qw+i);
    memset(ans,-1,sizeof(ans));
    for(int i=1;i<=tot;i++){
        int L=(i-1)*blo+1,R=min(q,i*blo);
        for(int j=L;j<=R;j++)//每块操作转化为差分
            if(ql[j]<=qr[j])d[ql[j]]+=qw[j],d[qr[j]+1]-=qw[j];
            else d[ql[j]]+=qw[j],d[m+1]-=qw[j],d[1]+=qw[j],d[qr[j]+1]-=qw[j];
        memset(sum,0,sizeof(sum));
        for(int j=1;j<=m;j++)a[j]=a[j-1]+d[j],sum[bel[j]]+=a[j];
        for(int k=1;k<=n;k++){
            if(ans[k]>=0||sum[k]<p[k])continue;
            ll s=sum[k];
            for(int j=R;j>=L;j--){//倒着扫
                for(int x:v[k]){
                    if(ql[j]<=qr[j])if(ql[j]<=x&&x<=qr[j])s-=qw[j];
                    if(ql[j]>qr[j])if(ql[j]<=x||x<=qr[j])s-=qw[j];
                }if(s<p[k]){ans[k]=j;break;}
            }
        }
    }for(int i=1;i<=n;i++)ans[i]>=0?printf("%d\n",ans[i]):puts("NIE");
    return 0;
}

标签:Meteors,int,题解,个数,差分,sqrt,操作,METEORS,ql
From: https://www.cnblogs.com/aday526/p/solution-sp10264.html

相关文章

  • CodeForces-300#B 题解
    题意给定\(n\)个数,保证\(n\mid3\),要将这\(n\)个数分配到\(\dfrac{n}{3}\)个三元组,有\(m\)个要求\(a,b\),每个要求表示\(a,b\)要在同一个三元组里,求最后的分......
  • P3874 砍树 题解
    前置树形dp,二分。题意本质上是一个树上背包,需要选不少于\(k\)个物品,每个物品有一个重量\(w\)和价值\(v\),求性价比最大值。分析既然是性价比,显然是分数规划。先......
  • CF992E Nastya and King-Shamans 题解
    传送门分析由于满足\(a_i\ge0\),所以\(s_i\)单调不减。当我们找到一个\(i\)时,不管\(i\)是否满足,下一个可能的一定大于等于\(a_i+s_{i-1}\)。而且\(a_i+s_{i-1}......
  • P8810 [蓝桥杯 2022 国 C] 数组个数 题解
    思路比较简单的一道题。用的五维dp,看到二维和三维的dp直接膜了orz。正文开始。分析不难看出dp。因为\(b_i\)的值只与\(a_{i-1},a_i,a_{i+1}\)有关,所以我们定......
  • CF939F Cutlet 题解
    题意简述有一个正反面都为\(0\)的卡片,每过\(1\)分朝下那一面的数值就会增加\(1\),你可以在几个区间的时间内翻转卡片,求经过\(2n\)秒后能否让这个卡片的正反面的数都......
  • YACS 11 月甲题解
    https://iai.sh.cn/contest这把还是简单的,难度对标普及组。所有题解均口胡。T1观察&性质你扫左端点,然后维护以当前左端点最长的合法子段,显然右端点单不降,因为当你......
  • 【LeetCode】题解合集(JavaScript版)
    前言:今年断断续续写了些LeetCode题目,一方面是为了一个比较现实的问题——面试,最重要的是要复习之前学习的数据结构与算法。后面有时间还会接续刷题…题解合集:题号题目题解1......
  • NOIP2022 题解
    终于有机会补NOIP的题了T1考虑枚举C与F的纵列考虑预处理出每个点最左边和最下边可以延伸到哪之后枚举列,然后对行做类似于扫描线的操作,统计有多少可行的"第一横行"......
  • NOIP2022 题解
    T2T3......
  • CF1408G 题解
    题意传送门给定\(n\)个点的带权无向完全图,点\(i,j\)之间的权值为\(a_{i,j}\),权值是一个\(1\sim\frac{n(n-1)}{2}\)的排列。计数把原图划分成\(k\)个组的方......