[Luogu3527][POI2011]MET-Meteors
sol
昨晚突发奇想去学了一下整体二分。
这道题应该算是整体二分的板子题吧。
整体二分
首先要求可离线,不然还是安心码数据结构吧。
整体二分简单的来讲,就是时间复杂度可以承受一次二分答案却无法承受每个询问都二分答案时(比如说依次二分的复杂度是\(O(n\log{n})\),那么\(Q\)次二分答案就是\(O(Qn\log{n})\)),我们把所有询问一起二分答案。往往会使用一些诸如树状数组之类的辅助工具。
拿这道题来讲
“每个国家最早多少次之后收集到指定数量的陨石?”
那么就二分一个时间\(mid\),然后判断前\(mid\)次之内是否达到了指定数量。
我们把所有国家放在一起做,每次二分出了\(mid\)之后,模拟\(l\)到\(mid\)这一段的陨石(当然是用树状数组统计啦),然后按照“是否已经达到指定数量”把所有国家分成两份。已经完成了的国家向左递归(因为答案可能会更小),没有完成的国家向右递归,同时指定数量\(p\)中减掉已收集的陨石数量即可。
code
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int N = 300005;
#define ll long long
int gi()
{
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
int n,m,k,p[N],st[N],ed[N],val[N],ans[N];
struct nation{ll p;int id;}q[N],q1[N],q2[N];
vector<int>a[N];
ll c[N];
void modify(int k,int v){while (k<=m) c[k]+=v,k+=k&-k;}
ll query(int k){ll s=0;while (k) s+=c[k],k-=k&-k;return s;}
void update(int p,int f)
{
if (st[p]<=ed[p])
modify(st[p],val[p]*f),modify(ed[p]+1,-val[p]*f);
else
modify(1,val[p]*f),modify(ed[p]+1,-val[p]*f),modify(st[p],val[p]*f);
}
void solve(int L,int R,int l,int r)//[L,R]是国家区间 [l,r]是二分的答案区间
{
if (L>R) return;
if (l==r)
{
for (int i=L;i<=R;i++)
ans[q[i].id]=l;
return;
}
int mid=l+r>>1;
int t1=0,t2=0;ll temp;
for (int i=l;i<=mid;i++) update(i,1);
for (int i=L;i<=R;i++)
{
temp=0;
for (int j=0,sz=a[q[i].id].size();j<sz;j++)
temp+=query(a[q[i].id][j]);
if (temp>=q[i].p) q1[++t1]=q[i];
else q[i].p-=temp,q2[++t2]=q[i];
}
for (int i=l;i<=mid;i++) update(i,-1);
for (int i=L,j=1;j<=t1;i++,j++) q[i]=q1[j];
for (int i=L+t1,j=1;j<=t2;i++,j++) q[i]=q2[j];
solve(L,L+t1-1,l,mid);solve(L+t1,R,mid+1,r);
}
int main()
{
n=gi();m=gi();
for (int i=1;i<=m;i++) a[gi()].push_back(i);
for (int i=1;i<=n;i++) q[i]=(nation){gi(),i};
k=gi();
for (int i=1;i<=k;i++) st[i]=gi(),ed[i]=gi(),val[i]=gi();
++k;st[k]=1;ed[k]=m;val[k]=1e9;//设置右哨兵保证所有国家都可以完成
solve(1,n,1,k);
for (int i=1;i<=n;i++)
if (ans[i]==k) puts("NIE");
else printf("%d\n",ans[i]);
return 0;
}
[Luogu3527][POI2011]MET-Meteors的更多相关文章
- Luogu-3527 [POI2011]MET-Meteors
Luogu-3527 [POI2011]MET-Meteors 题面 Luogu-3527 题解 感觉和上一那道题是一个类型的,直接二分答案,用BIT维护区间加(差分)即可 代码 #include&l ...
- 「POI2011」Meteors
「POI2011」Meteors 传送门 整体二分,树状数组实现区间修改单点查询,然后注意修改是在环上的. 参考代码: #include <cstdio> #include <vec ...
- Luogu3527 POI2011 Meteors 整体二分、树状数组、差分
传送门 比较板子的整体二分题目,时限有点紧注意常数 整体二分的过程中将时间在\([l,mid]\)之间的流星使用树状数组+差分进行维护,然后对所有国家查看一遍并分好类,递归下去,记得消除答案在\([m ...
- 【BZOJ】【2527】【POI2011】Meteors
整体二分+树状数组 整体二分……感谢zyf提供的入门题 简单粗暴的做法:枚举每一个国家,二分他的$w_i$,然后计算……然而这样效率很低…… 整体二分就是:对所有的国家一起进行二分,$w_i$在mid ...
- 【BZOJ2527】【POI2011】Meteors [整体二分]
Meteors Time Limit: 60 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 这个星球经常会下陨石雨.BI ...
- 【BZOJ】【2738】&【Tsinsen】【A1333】矩阵乘法
整体二分+树状数组 过了[BZOJ][2527][POI2011]Meteors以后这题就没那么难啦~ 关键是[从小到大]依次插入数字,然后整体二分每个查询的第k大是在第几次插入中被插入的……嗯大概就 ...
- BZOJ2527: [Poi2011]Meteors
补一发题解.. 整体二分这个东西,一开始感觉复杂度不是很靠谱的样子 问了po姐姐,说套主定理硬干.. #include<bits/stdc++.h> #define ll long lon ...
- 2527: [Poi2011]Meteors[整体二分]
2527: [Poi2011]Meteors Time Limit: 60 Sec Memory Limit: 128 MB Submit: 1528 Solved: 556 [Submit][S ...
- 【BZOJ2527】[Poi2011]Meteors 整体二分
[BZOJ2527][Poi2011]Meteors Description Byteotian Interstellar Union (BIU) has recently discovered a ...
随机推荐
- Linux终端下 dstat 监控工具
dstat 是一个可以取代vmstat,iostat,netstat和ifstat这些命令的多功能产品.dstat克服了这些命令的局限并增加了一些另外的功能,增加了监控项,也变得更灵活了.dstat可 ...
- 关于ssh登录出现异常警告:WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
提示警告信息如下: arnold@WSN:~$ ssh 10.18.46.111 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ...
- php详细学习1
PHP中的引用 $a="now magic"; $b=&$a; $b="abc"; echo $b.$a; 结果:abcabc $a="now ...
- js分页功能实现
实现一个js的分页并在弹出框中显示 1.分页插件使用:bootstarp-paginator.js,需要先引入bootstarp.js和jquery.js等: !function($){"u ...
- MySql 性能调优策略
本主题调优针对于my.cnf配置来做详细的参数说明 示例配置如下: #cat my.cnf # MySQL client library initialization. [client] port = ...
- JMeter之Http协议接口性能测试
一.不同角色眼中的接口 1.1,开发人员眼中的接口 1.2,测试人员眼中的接口 二.Http协议基本介绍 2.1,常见的接口协议 1.:2. :3. :4.:5.: 6. 2.2,Http协议栈 ...
- Java经典编程题50道之四十三
一个偶数总能表示为两个素数之和. public class Example43 { public static void main(String[] args) { f(); ...
- CodeForces - 681A A Good Contest
咳咳,从今天开始,每天做一个英语题,不论简单还是难,坚持到下学期的省赛,希望能有效果. 这题就是判断是否能成为red,如果他超越的人里面有在比赛前分数达到2400,并且在比赛后分数上升,那么他就能成为 ...
- UVA - 12333 字典树+大数
思路:用字典树将前40个数字记录下来,模拟大数加法即可. AC代码 #include <cstdio> #include <cmath> #include <algori ...
- scrapy 中日志的使用
我在后台调试 在后台调试scrapy spider的时候,总是觉得后台命令窗口 打印的东西太多了不便于观察日志,因此需要一个日志文件记录信息,这样以后会 方便查找问题. 分两种方法吧. 1.简单粗暴. ...