Machine Learning Codeforces - 940F(带修莫队) && 洛谷P4074 [WC2013]糖果公园
以下内容未验证,有错请指正...
设块大小为T,则块数为$\frac{n}{T}$
将询问分为$(\frac{n}{T})^2$块(按照左端点所在块和右端点所在块分块),同块内按时间从小到大依次处理
1.左/右端点块内移动总代价:$q*T$
2.时间的移动总代价:$(\frac{n}{T})^2*n$
总复杂度:$q*T+\frac{n^3}{T^2}$
好吧,事实上一般不会这么写。。。
一般只需要把询问按三个关键字(优先级:左端点所在块>右端点所在块>时间)排序,然后在任意两个询问间转移
一般的写法还要:
1.左端点块间移动代价:$n$
2.右端点块间移动代价:$\frac{n}{T}*n$
事实上是不影响的。。。
最优块大小?还真不会算,可以确定的是当$T=n^\frac{2}{3}$时,最终复杂度是(设n与q同阶)$n^{\frac{5}{3}}$
https://www.luogu.org/problemnew/show/CF940F
模板,跑一下就行了。。。
比较特别的是,要求的那个mex一定不会超过sqrt(n)级别(如果mex=k,说明查询的区间内至少有1+2+3+..+(k-1)=k*(k-1)/2个数),可以直接暴力跑(常数要小一点的话,就瞎维护一下(?讲不清楚啊))
upd:突然发现用以下的方法维护答案,复杂度好像不太对(n^(5/3)*sqrt(n)>n^2)?可能还是每次暴力找答案好?
错误记录:(都是一些很容易犯但是极其难发现的错误,要小心了)
1.题面有点绕,搞混了"数的出现次数"和"数的出现次数的出现次数"
2.75,83行成了"del(...);ins(...)";if没起到正确作用
3.最后输出的时候只枚举编号到了n,没有枚举到qq
4.修改时间时,没有判要del的是否本来就在里面(如75行的if),如果本来不在里面那么不要del也不要ins
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const int N=;
struct C
{
int p,a,b,t;//p位置从a改为b
}c[N];
int nc;
struct Q
{
int l,r,t,num;
}q[N];
int nq;
int nl,nr,nt,pc;
const int sz=;
int bl[N];
int ans[N];
int a[N],b[N];
bool c1(const Q &a,const Q &b)
{
return bl[a.l]<bl[b.l]
||(bl[a.l]==bl[b.l]&&bl[a.r]<bl[b.r])
||(bl[a.l]==bl[b.l]&&bl[a.r]==bl[b.r]&&a.t<b.t);
}
int n1[],n2[];
int nans;
int qn[N],cn[N];
int tt[];
map<int,int> ma;
void decn2(int x)
{
if(!x) return;
n2[x]--;
if(n2[x]==)
{
if(nans>x) nans=x;
}
}
void incn2(int x)
{
if(!x) return;
n2[x]++;
if(n2[x]==)
{
if(nans==x)
{
while(n2[nans]) nans++;
}
}
}
void ins(int x)
{
decn2(n1[x]);n1[x]++;incn2(n1[x]);
}
void del(int x)
{
decn2(n1[x]);n1[x]--;incn2(n1[x]);
}
void inctime()
{
while(pc+<=nc&&c[pc+].t<=nt)
{
pc++;
if(nl<=c[pc].p&&c[pc].p<=nr) del(c[pc].a),ins(c[pc].b);
a[c[pc].p]=c[pc].b;
}
}
void dectime()
{
while(pc>=&&c[pc].t>nt)
{
if(nl<=c[pc].p&&c[pc].p<=nr) del(c[pc].b),ins(c[pc].a);
a[c[pc].p]=c[pc].a;
pc--;
}
}
int n,qq;
int main()
{
int i,idx,l,r,p,x;
scanf("%d%d",&n,&qq);
for(i=;i<=n;i++) bl[i]=(i-)/sz;
for(i=;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i],tt[++tt[]]=a[i];
for(i=;i<=qq;i++)
{
scanf("%d",&idx);
if(idx==)
{
scanf("%d%d",&l,&r);
++nq;q[nq].l=l;q[nq].r=r;q[nq].t=nt;q[nq].num=i;
qn[i]=nq;
}
else
{
scanf("%d%d",&p,&x);tt[++tt[]]=x;
++nc;c[nc].p=p;c[nc].a=a[p];c[nc].b=x;
a[p]=x;
++nt;c[nc].t=nt;
cn[i]=nc;
}
}
for(i=;i<=n;i++) a[i]=b[i];
sort(tt+,tt+tt[]+);tt[]=unique(tt+,tt+tt[]+)-tt-;
for(i=;i<=tt[];i++) ma[tt[i]]=i;
for(i=;i<=n;i++) a[i]=ma[a[i]];
for(i=;i<=qq;i++)
if(cn[i])
{
c[cn[i]].a=ma[c[cn[i]].a];
c[cn[i]].b=ma[c[cn[i]].b];
}
/*
{
puts("Q");
for(i=1;i<=nq;i++)
{
printf("%d %d %d %d\n",q[i].l,q[i].r,q[i].t,q[i].num);
}
puts("C");
for(i=1;i<=nc;i++)
{
printf("%d %d %d %d\n",c[i].p,c[i].a,c[i].b,c[i].t);
}
}
*/
sort(q+,q+nq+,c1);
nl=;nr=;nt=;nans=;pc=;
for(i=;i<=nq;i++)
{
//printf("i%d %d\n",i,q[i].num);
while(nl>q[i].l) nl--,ins(a[nl]);
while(nr<q[i].r) nr++,ins(a[nr]);
while(nl<q[i].l) del(a[nl]),nl++;
while(nr>q[i].r) del(a[nr]),nr--;
if(nt<q[i].t) nt=q[i].t,inctime();
if(nt>q[i].t) nt=q[i].t,dectime();
ans[q[i].num]=nans;
}
for(i=;i<=qq;i++)
if(qn[i])
printf("%d\n",ans[i]);
return ;
}
https://www.luogu.org/problemnew/show/P4074
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
const ll N=;
struct E
{
ll to,nxt;
}e[N<<];
ll f1[N],ne;
ll n,m,qq;
ll v[N],w[N],a[N],cc2[N];
struct C
{
ll p,a,b;
}c[N];
ll nc;
struct Q
{
ll a,b,t,num;
}q[N];
ll nq;
ll cn[N],qn[N];
ll nl,nr,nt,nans,pc;
bool vis[N];
const ll sz=;
ll p[N<<],pl[N];
namespace LCA
{
ll anc[N][],l2n=,d[N];
void dfs(ll u,ll fa)
{
p[++p[]]=u;pl[u]=p[];
anc[u][]=fa;d[u]=d[fa]+;
for(ll i=;i<=l2n;i++)
anc[u][i]=anc[anc[u][i-]][i-];
for(ll k=f1[u];k;k=e[k].nxt)
if(e[k].to!=fa)
dfs(e[k].to,u);
p[++p[]]=u;
}
ll lft[];
void init()
{
ll i;
lft[]=;
for(i=;i<;i++) lft[i]=lft[i-]<<;
}
ll lca(ll a,ll b)
{
if(d[a]<d[b]) swap(a,b);
ll i,t=d[a]-d[b];
for(i=;t;t>>=,i++)
if(t&)
a=anc[a][i];
if(a==b) return a;
for(i=l2n;i>=;i--)
if(anc[a][i]!=anc[b][i])
{
a=anc[a][i];
b=anc[b][i];
}
return anc[a][];
}
}
using LCA::lca;
ll bl[N<<];
bool c1(const Q &a,const Q &b)
{
return bl[a.a]<bl[b.a]
||(bl[a.a]==bl[b.a]&&bl[a.b]<bl[b.b])
||(bl[a.a]==bl[b.a]&&bl[a.b]==bl[b.b]&&a.t<b.t);
}
ll ans[N];
ll nn[];
void change(ll x)
{
if(vis[x])
{
nans-=v[a[x]]*w[nn[a[x]]];
nn[a[x]]--;
}
else
{
nn[a[x]]++;
nans+=v[a[x]]*w[nn[a[x]]];
}
vis[x]^=;
}
void inctime()
{
while(pc+<=nc&&pc+<=nt)
{
pc++;
bool fl=vis[c[pc].p];
if(fl) change(c[pc].p);
a[c[pc].p]=c[pc].b;
if(fl) change(c[pc].p);
}
}
void dectime()
{
while(pc>=&&pc>nt)
{
bool fl=vis[c[pc].p];
if(fl) change(c[pc].p);
a[c[pc].p]=c[pc].a;
if(fl) change(c[pc].p);
pc--;
}
}
int main()
{
LCA::init();
ll i,x,y,idx,l;
scanf("%lld%lld%lld",&n,&m,&qq);
for(i=;i<=m;i++) scanf("%lld",&v[i]);
for(i=;i<=n;i++) scanf("%lld",&w[i]);
for(i=;i<n;i++)
{
scanf("%lld%lld",&x,&y);
e[++ne].to=y;e[ne].nxt=f1[x];f1[x]=ne;
e[++ne].to=x;e[ne].nxt=f1[y];f1[y]=ne;
}
for(i=;i<=n;i++) scanf("%lld",&a[i]),cc2[i]=a[i];
for(i=;i<=qq;i++)
{
scanf("%lld%lld%lld",&idx,&x,&y);
if(idx==)
{
++nc;
c[nc].p=x;c[nc].a=a[x];c[nc].b=y;a[x]=y;
cn[i]=nc;
}
else
{
++nq;
q[nq].a=x;q[nq].b=y;q[nq].t=nc;q[nq].num=i;
qn[i]=nq;
}
}
LCA::dfs(,);
for(i=;i<=nq;i++)
{
q[i].a=pl[q[i].a];
q[i].b=pl[q[i].b];
if(q[i].a>q[i].b) swap(q[i].a,q[i].b);
}
/*
for(i=1;i<=nc;i++)
{
c[i].p=pl[c[i].p];
}
*/
for(i=;i<=p[];i++) bl[i]=(i-)/sz;
sort(q+,q+nq+,c1);
for(i=;i<=n;i++) a[i]=cc2[i];
nl=;nr=;nt=;nans=;pc=;
for(i=;i<=nq;i++)
{
while(nl>q[i].a) --nl,change(p[nl]);
while(nr<q[i].b) ++nr,change(p[nr]);
while(nl<q[i].a) change(p[nl]),++nl;
while(nr>q[i].b) change(p[nr]),--nr;
if(nt<q[i].t) nt=q[i].t,inctime();
if(nt>q[i].t) nt=q[i].t,dectime();
l=lca(p[q[i].a],p[q[i].b]);
bool fl1=vis[p[q[i].a]],fl2=vis[p[q[i].b]];
bool fl3=vis[l];
if(!fl1) change(p[q[i].a]);
if(!fl2) change(p[q[i].b]);
if(!fl3) change(l);
ans[q[i].num]=nans;
if(!fl1) change(p[q[i].a]);
if(!fl2) change(p[q[i].b]);
if(!fl3) change(l);
}
for(i=;i<=qq;i++)
if(qn[i])
printf("%lld\n",ans[i]);
return ;
}
Machine Learning Codeforces - 940F(带修莫队) && 洛谷P4074 [WC2013]糖果公园的更多相关文章
- 洛谷P4074 [WC2013]糖果公园(莫队)
传送门 总算会树形莫队了…… 上次听说树形莫队是给树分块,实在看不懂.然后用括号序列的方法做总算能弄明白了 先说一下什么是括号序列,就是在$dfs$的时候,进入的时候记录一下,出去的时候也记录一下 拿 ...
- Machine Learning CodeForces - 940F (带修改的莫队)
You come home and fell some unpleasant smell. Where is it coming from? You are given an array a. You ...
- Machine Learning(CF940F+带修改莫队)
题目链接:http://codeforces.com/problemset/problem/940/F 题目: 题意:求次数的mex,mex的含义为某个集合(如{1,2,4,5})第一个为出现的非负数 ...
- CF940F Machine Learning(带修莫队)
首先显然应该把数组离散化,然后发现是个带修莫队裸题,但是求mex比较讨厌,怎么办?其实可以这样求:记录每个数出现的次数,以及出现次数的出现次数.至于求mex,直接暴力扫最小的出现次数的出现次数为0的正 ...
- Codeforces 1476G - Minimum Difference(带修莫队+根号平衡)
Codeforces 题目传送门 & 洛谷题目传送门 震惊!我竟然独立切掉了这道 *3100 的题! 虽然此题难度的确虚高,感觉真实评分也就 2800~2900 罢.但感觉还是挺有成就感的( ...
- 【BZOJ-3052】糖果公园 树上带修莫队算法
3052: [wc2013]糖果公园 Time Limit: 200 Sec Memory Limit: 512 MBSubmit: 883 Solved: 419[Submit][Status] ...
- 「洛谷1903」「BZOJ2120」「国家集训队」数颜色【带修莫队,树套树】
题目链接 [BZOJ传送门] [洛谷传送门] 题目大意 单点修改,区间查询有多少种数字. 解法1--树套树 可以直接暴力树套树,我比较懒,不想写. 稍微口胡一下,可以直接来一个树状数组套主席树,也就是 ...
- BZOJ2120 数颜色 莫队 带修莫队
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ2120.html 题目传送门 - BZOJ2120 题意 给定一个长度为 $n$ 的序列 $a$ ,有 ...
- BZOJ3052/UOJ#58 [wc2013]糖果公园 莫队 带修莫队 树上莫队
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ3052.html 题目传送门 - BZOJ3052 题目传送门 - UOJ#58 题意 给定一棵树,有 ...
随机推荐
- codeforces 463B Caisa and Pylons 解题报告
题目链接:http://codeforces.com/problemset/problem/463/B 题目意思:Caisa 站在 0 pylon 并且只有 0 energy,他需要依次跳过1 pyl ...
- 2013 gzhu 校赛
题目描述: Integer in C++ Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 128000/64000 KB (Java/Othe ...
- 万亿级日志与行为数据存储查询技术剖析——Hbase系预聚合方案、Dremel系parquet列存储、预聚合系、Lucene系
转自:http://www.infoq.com/cn/articles/trillion-log-and-data-storage-query-techniques?utm_source=infoq& ...
- 谈谈javaScript
谈谈javaScript (杰我学习) 一. 什么是JavaScript 人们通常所说的JavaScript,其正式名称为ECMAScript.这个标准由ECMA组织发展和维护.ECMA ...
- C++之const类成员变量,const成员函数
const修饰类的成员函数 const修饰变量一般有两种方式:const T *a,或者 T const *a,这两者都是一样的,主要看const位于*的左边还是右边,这里不再赘述,主要来看一下当co ...
- PHP mysql_fetch_array与mysql_fetch_row的区别
如果你的表里面有字段a,b,c那么你用mysql_fetch_row() 就返回array(1=>a的值,2=>b的值,3=>c的值)这个时候你读数组的话,只能这样写$array[1 ...
- vue-cli创建项目 一直downloading解决办法
vue-cli创建项目: 1 安装node(需要npm,npm是node的包管理股工具) 2 安装cnpm 3 安装vue-cli cnpm install vue-cli -g 4 创建 ...
- 使用 Git 命令去管理项目的版本控制(二)
参考 上一篇 完成本篇博客,本篇为作者原创,仅供学习参考. 本篇博文在上一篇的基础上这里记录了我的一个小模拟练习.本篇作为自己的学习笔记,也意在方便其他人的学习使用,达到分享目的.下面主要是操作截图 ...
- eclipse 怎么关闭 show children
转自:http://blog.51cto.com/swordbean/1736994 eclipse 关闭 show children 前段时间使用eclipse时,误按了 shift+alt+B结果 ...
- Unity4.0配置
关于Unity4.0的使用: 一 安装Unity 在程序包管理器控制台输入命令:Istall-Pckage unity.mvc安装后会在App_Start中生成UnityConfig.cs 和Unit ...